提问者:小点点

AngularJS对跨源资源执行OPTIONS HTTP请求


我试图设置AngularJS来与跨源资源通信,其中传递模板文件的资产主机位于不同的域上,因此AngularJS执行的XHR请求必须是跨域的。我已经为HTTP请求向服务器添加了适当的CORS头,以使其正常工作,但它似乎不起作用。问题是,当我在浏览器(chrome)中检查HTTP请求时,发送到资产文件的请求是一个选项请求(它应该是一个GET请求)。

我不确定这是AngularJS中的一个bug,还是我需要配置什么。据我所知,XHR包装器不能发出OPTIONS HTTP请求,因此在执行GET请求之前,浏览器似乎要先确定是否“允许”下载资产。如果是这种情况,那么我是否需要设置CORS头(access-control-allow-origin:http://asset.host.。。)还有资产主机吗?


共3个答案

匿名用户

选项请求绝不是AngularJS的bug,这是跨源资源共享标准强制浏览器的行为方式。请参阅本文档:https://developer.mozilla.org/en-us/docs/http_access_control,其中在“概述”部分指出:

跨源资源共享标准通过添加新的HTTP报头来工作,这些报头允许服务器描述允许使用web浏览器读取信息的源集。此外,对于可能对用户数据产生副作用的HTTP请求方法(特别是,对于GET以外的HTTP方法,或者对于某些MIME类型的POST用法)。该规范要求浏览器“预先处理”请求,使用HTTP OPTIONS请求头从服务器请求支持的方法,然后在服务器“批准”后,使用实际的HTTP请求方法发送实际的请求。服务器还可以通知客户端是否应该与请求一起发送“凭据”(包括Cookie和HTTP身份验证数据)。

很难提供适用于所有WWW服务器的通用解决方案,因为安装程序将根据服务器本身和您打算支持的HTTP谓词而有所不同。我鼓励您读读这篇出色的文章(http://www.html5rocks.com/en/tutorials/cors/),它详细介绍了服务器需要发送的确切头。

匿名用户

对于Angular 1.2.0RC1+,需要添加ResourceUrlWhiteList。

1.2:发布版本他们添加了一个escapeForRegexp函数,这样您就不必再转义字符串了。您可以直接添加url

'http://sub*.assets.example.com/**' 

确保为子文件夹添加**。下面是1.2的jsbin:http://jsbin.com/olavok/145/edit

1.2.0rc:如果您仍然使用rc版本,那么角度为1.2.0RC1的解决方案如下所示:

.config(['$sceDelegateProvider', function($sceDelegateProvider) {
     $sceDelegateProvider.resourceUrlWhitelist(['self', /^https?:\/\/(cdn\.)?yourdomain.com/]);
 }])

下面是一个jsbin示例,它适用于1.2.0RC1:http://jsbin.com/olavok/144/edit

Pre 1.2:对于较旧的版本(请参阅http://better-inter.net/enabling-cors-in-angular-js/),您需要在配置中添加以下两行:

$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];

下面是一个jsbin示例,它适用于1.2之前的版本:http://jsbin.com/olavok/11/edit

匿名用户

注意:不确定它与最新版本的Angular一起工作。

原件:

也可以覆盖选项请求(仅在Chrome中测试过):

app.config(['$httpProvider', function ($httpProvider) {
  //Reset headers to avoid OPTIONS request (aka preflight)
  $httpProvider.defaults.headers.common = {};
  $httpProvider.defaults.headers.post = {};
  $httpProvider.defaults.headers.put = {};
  $httpProvider.defaults.headers.patch = {};
}]);