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-HeadersAccess-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 选项

AngularJS——创建自定义数据绑定和 ng-repeat

AngularJs模板标签有时不评估

preflight request预检请求

使用AngularJs隐藏表列和行

Preflight(options) 请求的正确成功状态代码是啥? [复制]