在This question之后,我将rest控制器行为设置为
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前端
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过滤器后,会有什么问题呢?
我还检查了This link和this one,但没有解决问题
6条答案
按热度按时间4dc9hkyq1#
如果CORS头出现任何问题,我建议使用以下指令:
1.将cors配置添加到您的控制器。例如:
1.上面的代码会给response**添加特殊的http-headers。使用浏览器调试工具检查http-headers:
1.请求http头必须包含
Origin
。它将由浏览器自动添加在跨域 AJAX 。这个http-header也可以通过你的JS库添加。如果没有这个http-header,corsFilter
将无法工作。1.响应http header应该包含
Access-Control-*
header。这个HTTP头将由corsFilter
添加。1.如果你在响应中没有看到这些http头,可能意味着
\yii\filters\Cors
不工作或与其他过滤器冲突。1.检查控制器中的其他行为/过滤器。尝试添加
corsFilter
作为第一个行为**。可能是其他一些行为阻止了corsFilter
的执行。1.尝试禁用此控制器的CSRF验证(可能会阻止外部访问):
1.如果您使用authenticatorfilter(例如,您的控制器扩展了
yii\rest\ActiveController
),则必须在验证方法之前应用CORS filter。此外,必须对CORS Preflight请求禁用身份验证,以便浏览器可以安全地确定是否可以预先发出请求,而无需发送身份验证凭据。1.此外,还应检查您的Web服务器。可能nginx需要额外配置,apache可能需要重启。
1.响应中的
Access-Control-*
标头可以使用web服务器添加(有关apache和nginx,请参见)。但我不建议使用这种方式,因为在这种情况下,您无法使用应用程序管理http-haders。hm2xizp92#
试试这个:
在您的控制器上添加此功能。
而One Thing angular2在第一次使用OPTION方法,因此也允许OPTION方法
brccelvz3#
当前端在默认端口(80)以外的端口上运行时,就会出现问题。
然后在yii中你需要指定工作的端口。示例:前端在Yii cors set中运行
http: // localhost: 3000
:如果你没有指定端口(3000),Yii默认解释端口,结果是:
ykejflvf4#
最后,我有答案,可能是一个傻瓜证明一个,虽然这里回答的大多数事情都是好的,但没有什么对我有用,除非我真的明白这个问题正在发生什么。
正如一些人正确地说,浏览器往往发送选项在飞行前,所以要确保你的每个控制器,如果定制能够处理选项请求,如果不是你会像我一样徘徊年龄,有什么错,我已经配置了一切就像在文档中描述的,实现一切都是大家在网上说.
我只是在这里给你几个例子,希望这将有助于实现上述所有的解决方案后仍然没有工作,除非我添加了一个特定的功能,我的控制器actionOptions,像下面这样的东西
和修改的行为简单地描述在Yii文档
这在我的chrome浏览器上工作得很好。
现在,如果你有一些custome路线设置,就像我为我的一个控制器
示例:
GET v1/users/profile您必须将另一个路由也设置为OPTIONS v1/users/profile。
最后但并非最不重要的一点是,在某些情况下,您的某个操作可能会被进一步定制,或者只是使用标准操作,例如我的actionIndex
我添加了标题,具体如下在顶部的行动,就像下面的行动索引
我希望这会对你们中的一些人有所帮助:)。
4xrmg8kj5#
写$behaviors ['access'] ie很重要。AccessControl作为最后一个参数,例如:
yyhrrdl86#
我的解决方法是:
我也有配置为:在UrlManger中提到控制器名称