AngularJS 的 Preflight OPTIONS 请求不适用于 Chrome?
Posted
技术标签:
【中文标题】AngularJS 的 Preflight OPTIONS 请求不适用于 Chrome?【英文标题】:Preflight OPTIONS request by AngularJS not working with Chrome? 【发布时间】:2015-02-28 00:41:38 【问题描述】:我使用托管here 的AngularJS 开发了一个简单的应用程序。我正在使用我自己在 Laravel 中开发的 API,托管 here。当我尝试使用 Firefox 登录应用程序时,它运行良好。我的 API 接受飞行前 OPTIONS 请求并以 200 OK 响应。最后 POST 请求生成一个令牌,用户登录。
另一方面,当 Chrome 发送飞行前 OPTIONS 请求时,它收到一个 403 回复,并在控制台中给我这个错误:
XMLHttpRequest cannot load http://angulairapi.rohanchhabra.in/auth. Invalid HTTP status code 403
我也尝试通过 Postman REST 客户端在 /auth 上发送 OPTIONS 请求,它按预期返回 200 OK。为什么 Chrome 会有这样的行为?我错过了什么?
【问题讨论】:
缺少Access-Control-Allow-Headers
和Access-Control-Allow-Methods
,您能否在回复中也将它们发送为 *
【参考方案1】:
访问控制是服务器的职责,你需要在 Laravel 中配置它。
使用这个包:Laravel Cors这很有帮助。
【讨论】:
对不起,有点晚了,但是当我尝试像 boomerang 这样的 Soap 客户端时,我尝试访问的跨域服务器工作正常,但当我从 localhost 尝试时却无法正常工作。为什么会这样?【参考方案2】:首先,您必须发送这些标头(通配符有时不正确):
Access-Control-Allow-Headers: X-Requested-With, content-type
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
第二个(也是重要的)从配置中的 AngularJs 服务 $httpProvider 中删除标头:
myApp.config(['$httpProvider', function($httpProvider)
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
]);
【讨论】:
【参考方案3】:在filters.php (Laravel 4.2)
在下面添加
App::before(function($request)
// Enable CORS
// In production, replace * with http://yourdomain.com
header("Access-Control-Allow-Origin: *");
//header('Access-Control-Allow-Credentials: true'); optional
if (Request::getMethod() == "OPTIONS")
// The client-side application can set only headers allowed in Access-Control-Allow-Headers
$headers = [
'Access-Control-Allow-Methods'=> '*',
'Access-Control-Allow-Headers'=> '*'
];
return Response::make('You are connected to the API', 200, $headers);
);
您可以更改Access-Control-*
的值以满足您的需要
【讨论】:
【参考方案4】:在 Laravel 中,尝试将:'Access-Control-Allow-Methods'
& 'Access-Control-Allow-Headers'
设置为 '*'
public function handle($request, Closure $next)
header("Access-Control-Allow-Origin: *");
// ALLOW OPTIONS METHOD
$headers = [
'Access-Control-Allow-Methods'=> '*',
'Access-Control-Allow-Headers'=> '*'
];
if($request->getMethod() == "OPTIONS")
// The client-side application can set only headers allowed in Access-Control-Allow-Headers
return Response::make('OK', 200, $headers);
$response = $next($request);
foreach($headers as $key => $value)
$response->header($key, $value);
return $response;
【讨论】:
我不明白。我应该把这个函数准确地放在哪里?【参考方案5】:“访问控制请求标头:接受”中的问题。 您需要在“Access-Control-Allow-Headers”中添加“accept”。
比较这两个请求:
Chrome:403 禁止 curl 'http://angulairapi.rohanchhabra.in/auth' -X OPTIONS -H 'Access-Control-Request-Method: POST' /angulair.rohanchhabra.in' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: ru -RU,ru;q=0.8,en-US;q=0.6,en;q=0.4' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (Khtml, like Gecko ) Chrome/39.0.2171.95 Safari/537.36' -H 'Accept: /' -H 'Referer: http://angulair.rohanchhabra.in/' -H 'Connection: keep-alive' -H 'Access-Control-Request -Headers:接受,内容类型'-v
火狐:200 正常 curl 'http://angulairapi.rohanchhabra.in/auth' -X OPTIONS -H '访问控制请求方法:POST' -H '来源:http://angulair.rohanchhabra.in' -H '接受编码:gzip、deflate、sdch' -H '接受语言: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4' -H '用户代理: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML,像 Gecko) Chrome/39.0.2171.95 Safari/537.36' -H 'Accept: /' -H 'Referer: http://angulair.rohanchhabra.in/' -H 'Connection: keep-alive' -H 'Access-Control -Request-Headers: content-type' -v
【讨论】:
我添加了“接受”标题以及“接受”标题。还是不行? gitlab.learningtechasia.com:8901/rohan0793/angulairapi.git 如果您愿意,可以查看 API 的存储库。它是公开的。以上是关于AngularJS 的 Preflight OPTIONS 请求不适用于 Chrome?的主要内容,如果未能解决你的问题,请参考以下文章
Django Rest Framework/Angular JS Preflight 选项