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 过滤器
And now the cors filters
// add CORS filter
$behaviors['corsFilter'] = [
'class' => yiifiltersCors::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:
将 cors 配置添加到您的控制器.例如:
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' => yiifiltersCors::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-headers.使用浏览器调试工具检查 http 标头:
The above code will add to response special http-headers. Check http-headers using browser debug tools:
请求 http 标头 应包含 Origin
.它将在跨域 AJAX 中由浏览器自动添加.这个 http-header 也可以通过你的 JS 库添加.没有这个 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 标头 响应,可能意味着 yiifiltersCors
不起作用或与其他过滤器.
If you don't see these http headers in response, probably it means that yiifiltersCors
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 yiiwebController::$enableCsrfValidation}.
*/
public $enableCsrfValidation = false;
// ...
}
如果您使用 authenticator 过滤器(例如,您的控制器扩展了 yiiestActiveController
),则必须在 应用之前应用 CORS 过滤器身份验证方法.此外,还必须为 CORS 预检请求禁用身份验证,以便浏览器可以安全地确定是否可以预先发出请求,而无需发送身份验证凭据.
If you are using authenticator filter (for example, your controller extends yiiestActiveController
) 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 yiifiltersauthHttpBasicAuth;
public function behaviors()
{
$behaviors = parent::behaviors();
// remove authentication filter
$auth = $behaviors['authenticator'];
unset($behaviors['authenticator']);
// add CORS filter
$behaviors['corsFilter'] = [
'class' => yiifiltersCors::className(),
];
// re-add authentication filter
$behaviors['authenticator'] = $auth;
// avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
$behaviors['authenticator']['except'] = ['options'];
return $behaviors;
}
另外应该检查您的网络服务器.可能 nginx 可能需要额外配置,apache 可能需要重启.
Access-Control-*
响应头可以使用 web-server 添加(参见 apache 和 nginx).但我不建议使用这种方式,因为在这种情况下,您无法使用 application.properties 管理 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:如何在非RESTful API
相关文章