angularjs - Yii2 REST+ Angular 跨域 CORS

标签 angularjs rest yii2 yii2-advanced-app yii-components

我开发了 Angular & Yii2 REST 服务。跨域有问题。
在下面添加我的 angular & Yii2 REST 代码。

AngularJs : (如' http://organization1.example.com ',' http://organization2.example.com ',....)

$http.defaults.useXDomain = true;
$http.defaults.withCredentials = true;
$http.defaults.headers.common['Authorization'] = 'Bearer ' + MYTOKEN

我来自 Angular Controller 的请求:
apiURL = 'http://api.example.com';
$http.get(apiURL + '/roles')
     .success(function (roles) { })
     .error(function () { });

Yii2 .htaccess:(REST URL 像“http://api.example.com”)
Header always set Access-Control-Allow-Origin: "*"
Header always set Access-Control-Allow-Credentials: true
Header always set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Authorization,X-Requested-With, content-type"

Yii2 我的行为:
public function behaviors() {
    $behaviors = parent::behaviors();
    $behaviors['corsFilter'] = [
        'class' => Cors::className(),
        'cors' => [
            'Origin' => ['*'],
            'Access-Control-Expose-Headers' => [
                'X-Pagination-Per-Page',
                'X-Pagination-Total-Count',
                'X-Pagination-Current-Page',
                'X-Pagination-Page-Count',
            ],
        ],
    ];
    $behaviors['authenticator'] = [
        'class' => HttpBearerAuth::className(),
        'except' => ['options'],
    ];
    $behaviors['contentNegotiator'] = [
        'class' => ContentNegotiator::className(),
        'formats' => [
            'application/json' => Response::FORMAT_JSON,
        ],
    ];

    return $behaviors;
}

问题

从我的 Angular 请求是 'GET' 方法,但它会转为 'OPTIONS' 方法并返回 401 未经授权的错误(CORS)。因为请求授权头没有发送。

最佳答案

更新:

正如@jlapoutre 所指出的,现在已经很好地描述了 in official docs :

Adding the Cross-Origin Resource Sharing filter to a controller is a bit more complicated than adding other filters described above, because the CORS filter has to be applied before authentication methods and thus needs a slightly different approach compared to other filters. Also authentication has to be disabled for the CORS Preflight requests so that a browser can safely determine whether a request can be made beforehand without the need for sending authentication credentials. The following shows the code that is needed to add the yii\filters\Cors filter to an existing controller that extends from yii\rest\ActiveController:

use yii\filters\auth\HttpBasicAuth;

public function behaviors()
{
    $behaviors = parent::behaviors();

    // remove authentication filter
    $auth = $behaviors['authenticator'];
    unset($behaviors['authenticator']);

    // add CORS filter
    $behaviors['corsFilter'] = [
        'class' => \yii\filters\Cors::className(),
    ];

    // re-add authentication filter
    $behaviors['authenticator'] = $auth;
    // avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
    $behaviors['authenticator']['except'] = ['options'];

    return $behaviors;
}


旧答案 (已弃用)

parent::behaviors() 合并时存在排序问题.完整详情 here .

我建议在与父数组合并时不要定义键:
public function behaviors()
{
    return \yii\helpers\ArrayHelper::merge([
        [
            'class' => \yii\filters\Cors::className(),
            'cors' => [...],
        ],
        [
            'class' => \yii\filters\auth\HttpBearerAuth::className(),
            'except' => ['options'],
        ],
        [
            'class' => ContentNegotiator::className(),
            'formats' => [...],
        ]
    ], parent::behaviors());
}

关于angularjs - Yii2 REST+ Angular 跨域 CORS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35359365/

相关文章:

html - 当 ng-click 在 div 内时,ng-show 不会更新

javascript - 在 AngularJS 服务中缓存 Promise 对象

java - 如何在没有 xml 的 Spring MVC 中启用 REST gzip 压缩?

c# - 如何使用 Advanced Rest Client 发出 POST 请求

php - 在 Yii2 中上传图片和验证

javascript - AngularJS:从选择选项更新表内容

javascript - 在 Angular 加载后加载 Jade 并解析所有变量

bash:在循环中 curl 并行请求

forms - Yii2:如何为 activeform 使用自定义验证功能?

yii2.如何在dataProvider中设置场景?