繁体   English   中英

yii2 restful api:(原因:缺少 CORS 标头“Access-Control-Allow-Origin”)

[英]yii2 restful api: (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)

我想将 React 与 Yii2 RESTful 结合使用,我创建了一个这样的用户控制器:

<?php
namespace app\controllers;
use yii\rest\ActiveController;

class UsersController extends ActiveController
{
    public $modelClass = 'app\models\User';
}

当在浏览器中打开链接显示我的用户时,当我想在反应中使用axios时,我在浏览器控制台收到错误消息:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/rest/web/users. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

但是当我在 firefox 开发人员工具中检查network时,我发现 axios 请求及其状态为 200 并正确接收响应。

我尝试在我的控制器中使用behaviors功能,如下所示:

public function behaviors()
{
    return [
        'corsFilter' => [
            'class' => \yii\filters\Cors::className(),
            'cors' => [
                'Origin' => ['*'],
                'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
                'Access-Control-Request-Headers' => ['*'],
            ],

        ],
    ];
}

但得到错误

无效参数 – yii\base\InvalidArgumentException 响应内容不能是数组。

我该如何解决这个问题?

更新

更新了答案,因为实现的逻辑允许每个请求绕过身份验证过滤器(感谢@KalyanHalderRaaz指出错误)。

有两件事要改变

  • 重新添加过滤器时,最好指定您正在使用的身份验证。 更改下面的代码

    // re-add authentication filter $behaviors['authenticator'] = $auth;

    下面,我以BasicAuth为例。

     $behaviors['authenticator'] = [ 'class' => yii\filters\auth\HttpBasicAuth::class ];
  • 添加beforeAction()时不要忘记将逻辑包装在if(parent::beforeAction($action))中,否则它会验证每个请求,因为我们只是在此处为每个请求返回true ,并且不会调用会触发过滤器。

    beforeAction()替换为以下内容

    public function beforeAction($action) { if (parent::beforeAction($action)) { \Yii::$app->response->format = Response::FORMAT_JSON; return true; } }

只需确保您覆盖了用户身份模型中的findIdentityByAccessToken()


根据文档,您应该首先取消设置authenticator器过滤器以添加Cors过滤器,因此您的行为应该看起来像

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

    // remove authentication filter necessary because we need to 
    // add CORS filter and it should be added after the CORS
    unset($behaviors['authenticator']);

    // add CORS filter
    $behaviors['corsFilter'] = [
        'class' => '\yii\filters\Cors',
        'cors' => [
            'Origin' => ['*'],
            'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
            'Access-Control-Request-Headers' => ['*'],
        ],
    ];

    // re-add authentication filter of your choce
    $behaviors['authenticator'] = [
        'class' => yii\filters\auth\HttpBasicAuth::class
    ];

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

您可以通过添加如下所示的beforeAction将响应格式设置为控制器内的 json

public function beforeAction($action)
{
    if (parent::beforeAction($action)) {
        \Yii::$app->response->format = Response::FORMAT_JSON;
        return true;
    }

}

另一种可能的解决方案是定义虚拟主机。 当我将 API URL 设置为 http://localhost:8080/ 或http://127.0.0.1:8080/时,我遇到了类似的问题

通过在 XAMMP 中定义虚拟主机并将其映射到 127.0.0.1,问题就消失了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM