AngularJS 提出的预检选项请求不适用于 Chrome?
Preflight OPTIONS request by AngularJS not working with Chrome?
我使用 AngularJS 托管 here. I am consuming an API I developed myself in Laravel hosted 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-Request-Headers: accept" 中的问题。
您需要将 "accept" 添加到您的 "Access-Control-Allow-Headers".
比较这两个请求:
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: accept, content-type' -v
Firefox:200 正常
curl 'http://angulairapi.rohanchhabra.in/auth' -X OPTIONS -H 'Access-Control-Request-Method: POST' -H 'Origin: http://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: content-type' -v
在 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;
}
在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-*
的值以满足您的需要
首先你必须发送那些 Headers(通配符有时不正确):
Access-Control-Allow-Headers: X-Requested-With, content-type
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
第二步(也是重要的)从配置中的 AngularJs 服务 $httpProvider 中删除 header:
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
访问控制是服务器的职责,您需要在 Laravel 中配置它。
使用这个包:Laravel Cors这很有帮助。
我使用 AngularJS 托管 here. I am consuming an API I developed myself in Laravel hosted 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-Request-Headers: accept" 中的问题。 您需要将 "accept" 添加到您的 "Access-Control-Allow-Headers".
比较这两个请求:
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: accept, content-type' -v
Firefox:200 正常 curl 'http://angulairapi.rohanchhabra.in/auth' -X OPTIONS -H 'Access-Control-Request-Method: POST' -H 'Origin: http://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: content-type' -v
在 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;
}
在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-*
的值以满足您的需要
首先你必须发送那些 Headers(通配符有时不正确):
Access-Control-Allow-Headers: X-Requested-With, content-type
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
第二步(也是重要的)从配置中的 AngularJs 服务 $httpProvider 中删除 header:
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
访问控制是服务器的职责,您需要在 Laravel 中配置它。
使用这个包:Laravel Cors这很有帮助。