我试图设置AngularJS来与跨源资源通信,其中传递模板文件的资产主机位于不同的域上,因此AngularJS执行的XHR请求必须是跨域的。我已经为HTTP请求向服务器添加了适当的CORS头,以使其正常工作,但它似乎不起作用。问题是,当我在浏览器(chrome)中检查HTTP请求时,发送到资产文件的请求是一个选项请求(它应该是一个GET请求)。
我不确定这是AngularJS中的一个bug,还是我需要配置什么。据我所知,XHR包装器不能发出OPTIONS HTTP请求,因此在执行GET请求之前,浏览器似乎要先确定是否“允许”下载资产。如果是这种情况,那么我是否需要设置CORS头(access-control-allow-origin:http://asset.host.。。)还有资产主机吗?
选项请求绝不是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 = {};
}]);