Yii2 cors过滤器错误,提示不存在"Access-Control-Allow-Origin"标头 [英] Yii2 cors filters error that No 'Access-Control-Allow-Origin' header is present

查看:1035
本文介绍了Yii2 cors过滤器错误,提示不存在"Access-Control-Allow-Origin"标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按照此问题,我将我的休息控制器行为设置为

Following This question i have set my rest controller behaviour as

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

    $auth= $behaviors['authenticator'] = [
        'class' => HttpBearerAuth::className(),
        'only' => ['dashboard'],
    ];
    $behaviors['contentNegotiator'] = [
        'class' => ContentNegotiator::className(),
        'formats' => [
            'application/json' => Response::FORMAT_JSON,
        ],
    ];
    $acces=$behaviors['access'] = [
        'class' => AccessControl::className(),
        'only' => ['login'],
        'rules' => [
            [
                'actions' => ['login'],
                'allow' => true,
                'roles' => ['?'],
            ],
        ],
    ];

    unset($behaviors['authenticator']);
    unset($behaviors['access']);

现在是cors过滤器

    // add CORS filter
    $behaviors['corsFilter'] = [
        'class' => \yii\filters\Cors::className(),
          'cors' => [
        // restrict access to
        'Access-Control-Allow-Origin' => ['*'],
        'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
        // Allow only POST and PUT methods
        'Access-Control-Request-Headers' => ['*'],
        // Allow only headers 'X-Wsse'
        'Access-Control-Allow-Credentials' => true,
        // Allow OPTIONS caching
        'Access-Control-Max-Age' => 86400,
        // Allow the X-Pagination-Current-Page header to be exposed to the browser.
        'Access-Control-Expose-Headers' => [],
      ]
    ];

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

我的angular2前端为

An my angular2 frontend as

    const body = JSON.stringify(user);
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Content-Type', 'application/json');
headers.append('Access-Control-Allow-Credentials', "*");
return this._http.post(this.loginUrl, body, { headers:headers })
  .map((response: Response) => {
     //process response
  })
.catch(this.handleError);

但是仍然出现错误

Response to preflight request doesn't pass access control check: No
 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 
 'http://localhost:3000' is therefore not allowed access.

可能有什么问题,因为我在yii2行为中设置了cors过滤器未设置身份验证器,并在以后添加了它 我可能会错过什么

What could be wrong since ive set the cors filter in yii2 behaviours unset authenticator and added it later What could i be missing out

我还检查了此链接以及这个 但没有一个能解决问题

I have also checked on This link and also this one but none solves the issue

推荐答案

如果CORS标头出现任何问题,我建议使用以下说明:

In case of any problems with CORS headers, I recommend to use following instruction:

  1. 将cors配置添加到控制器.例如:

  1. Add cors configuration to your controller. For instance:

/**
 * List of allowed domains.
 * Note: Restriction works only for AJAX (using CORS, is not secure).
 *
 * @return array List of domains, that can access to this API
 */
public static function allowedDomains() {
    return [
        // '*',                        // star allows all domains
        'http://test1.example.com',
        'http://test2.example.com',
    ];
}

/**
 * @inheritdoc
 */
public function behaviors() {
    return array_merge(parent::behaviors(), [

        // For cross-domain AJAX request
        'corsFilter'  => [
            'class' => \yii\filters\Cors::className(),
            'cors'  => [
                // restrict access to domains:
                'Origin'                           => static::allowedDomains(),
                'Access-Control-Request-Method'    => ['POST'],
                'Access-Control-Allow-Credentials' => true,
                'Access-Control-Max-Age'           => 3600,                 // Cache (seconds)
            ],
        ],

    ]);
}

  • 上面的代码将添加以响应特殊的HTTP标头.使用浏览器调试工具检查http-header:

  • The above code will add to response special http-headers. Check http-headers using browser debug tools:

    请求http标头应包含Origin.浏览器会在Crossdomain AJAX中自动添加它.也可以通过您的JS库添加此http-header.没有这个http-header corsFilter将无法工作.

    Request http header should contain Origin. It will be added by browser automatically at Crossdomain AJAX. This http-header can be added also via your JS library. Without this http-header corsFilter won't work.

    POST /api/some-method-name HTTP/1.1
    Host: api.example.com
    Connection: keep-alive
    Content-Length: 86
    Accept: */*
    Origin: https://my-site.example.com
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    Referer: https://my-site.example.com/
    Accept-Encoding: gzip, deflate, br
    Accept-Language: en-GB,en;q=0.8,en-US;q=0.6,ru;q=0.4
    

  • 响应的HTTP标头应包含Access-Control-*标头.此http标头将由corsFilter添加.

  • Response http headers should contain Access-Control-* headers. This http-header will be added by corsFilter.

    HTTP/1.1 200 OK
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Origin: https://my-site.example.com
    Content-Type: application/json; charset=UTF-8
    Date: Fri, 24 Feb 2017 09:21:47 GMT
    Server: Apache
    Content-Length: 27
    Connection: keep-alive
    

  • 如果您没有在响应中看到这些http标头 ,则可能表示\yii\filters\Cors不起作用或与其他过滤器冲突.

  • If you don't see these http headers in response, probably it means that \yii\filters\Cors doesn't work or conflicts with other filters.

    检查控制器中的其他行为/过滤器.尝试将corsFilter添加为第一个行为.可能还有其他一些行为阻止了corsFilter的执行.

    Check other behaviors/filters in controller. Try add corsFilter as first behavior. Probably some other behaviors prevents execution of corsFilter.

    尝试为此控制器禁用CSRF验证(这可能会阻止外部访问):

    Try to disable CSRF validation for this controller (it may prevent external access):

    /**
     * Controller for API methods.
     */
    class ApiController extends Controller
    {
    
        /**
         * @var bool See details {@link \yii\web\Controller::$enableCsrfValidation}.
         */
        public $enableCsrfValidation = false;
    
        // ...
    }
    

  • 如果您使用的是 authenticator 过滤器(例如,您的控制器扩展了yii\rest\ActiveController),则必须在身份验证方法之前应用CORS过滤器.另外,必须禁用CORS Preflight请求的身份验证,以便浏览器可以安全地确定是否可以事先发出请求,而无需发送身份验证凭据.

  • If you are using authenticator filter (for example, your controller extends yii\rest\ActiveController) the CORS filter has to be applied BEFORE authentication methods. 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.

    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;
    }
    

  • 还应该检查您的Web服务器.可能nginx可能需要其他配置,而apache可能需要重新启动.

    Access-Control-*标头(请参见 apache nginx ).但我不建议使用这种方式,因为在这种情况下,您将无法使用应用程序管理http-haders.

    Access-Control-* headers in response can be added using web-server (see for apache and nginx). But I don't recommend to use this way, because in this case you can't manage http-haders using application.

    一些有用的信息可以在这里找到:

    Some useful information can be found here:

    这篇关于Yii2 cors过滤器错误,提示不存在"Access-Control-Allow-Origin"标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆