I'm trying to setup AngularJS to communicate with a cross-origin resource where the asset host which delivers my template files is on a different domain and therefore the XHR request that angular performs must be cross-domain. I've added the appropriate CORS header to my server for the HTTP request to make this work, but it doesn't seem to work. The problem is that when I inspect the HTTP requests in my browser (chrome) the request sent to the asset file is an OPTIONS request (it should be a GET request).

我不确定这是AngularJS中的一个bug,还是我需要配置一些东西。根据我的理解,XHR包装器不能做出一个OPTIONS HTTP请求,所以看起来就像浏览器在执行GET请求之前试图弄清楚是否“允许”首先下载资产。如果是这种情况,那么我是否需要与资产主机一起设置CORS头(Access-Control-Allow-Origin: http://asset.host…)?


当前回答

以下是我在ASP上修复这个问题的方法。网

First, you should add the nuget package Microsoft.AspNet.WebApi.Cors Then modify the file App_Start\WebApiConfig.cs public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.EnableCors(); ... } } Add this attribute on your controller class [EnableCors(origins: "*", headers: "*", methods: "*")] public class MyController : ApiController { [AcceptVerbs("POST")] public IHttpActionResult Post([FromBody]YourDataType data) { ... return Ok(result); } } I was able to send json to the action by this way $http({ method: 'POST', data: JSON.stringify(data), url: 'actionurl', headers: { 'Content-Type': 'application/json; charset=UTF-8' } }).then(...)

参考: 在ASP中启用跨源请求。NET Web API 2

其他回答

对于一个带有API的IIS MVC 5 / Angular CLI(是的,我很清楚你的问题是Angular JS)项目,我做了以下工作:

网络。在<system. Config。网络服务器>节点

    <staticContent>
      <remove fileExtension=".woff2" />
      <mimeMap fileExtension=".woff2" mimeType="font/woff2" />
    </staticContent>
    <httpProtocol>
      <customHeaders>
        <clear />
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type, atv2" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS"/>
      </customHeaders>
    </httpProtocol>

global.asax.cs

protected void Application_BeginRequest() {
  if (Request.Headers.AllKeys.Contains("Origin", StringComparer.OrdinalIgnoreCase) && Request.HttpMethod == "OPTIONS") {
    Response.Flush();
    Response.End();
  }
}

这应该可以解决MVC和WebAPI的问题,而不需要做所有其他的事情。然后我在Angular CLI项目中创建了一个HttpInterceptor,它会自动添加相关的头信息。希望这能帮助有类似情况的人。

对于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 rc:如果你仍然使用rc版本,Angular 1.2 rc1的解决方案是这样的:

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

下面是一个适用于1.2 rc1的jsbin示例: http://jsbin.com/olavok/144/edit


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

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

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

注意:不确定它是否适用于最新版本的Angular。

原:

也可以覆盖OPTIONS请求(仅在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 = {};
}]);

以下是我在ASP上修复这个问题的方法。网

First, you should add the nuget package Microsoft.AspNet.WebApi.Cors Then modify the file App_Start\WebApiConfig.cs public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.EnableCors(); ... } } Add this attribute on your controller class [EnableCors(origins: "*", headers: "*", methods: "*")] public class MyController : ApiController { [AcceptVerbs("POST")] public IHttpActionResult Post([FromBody]YourDataType data) { ... return Ok(result); } } I was able to send json to the action by this way $http({ method: 'POST', data: JSON.stringify(data), url: 'actionurl', headers: { 'Content-Type': 'application/json; charset=UTF-8' } }).then(...)

参考: 在ASP中启用跨源请求。NET Web API 2

OPTIONS请求绝不是AngularJS的错误,这是跨源资源共享标准要求浏览器的行为。请参考此文件:https://developer.mozilla.org/en-US/docs/HTTP_access_control,其中“概述”部分说:

The Cross-Origin Resource Sharing standard works by adding new HTTP headers that allow servers to describe the set of origins that are permitted to read that information using a web browser. Additionally, for HTTP request methods that can cause side-effects on user data (in particular; for HTTP methods other than GET, or for POST usage with certain MIME types). The specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request header, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method. Servers can also notify clients whether "credentials" (including Cookies and HTTP Authentication data) should be sent with requests.

提供一个适用于所有WWW服务器的通用解决方案是非常困难的,因为设置取决于服务器本身和你打算支持的HTTP动词。我鼓励您阅读这篇优秀的文章(http://www.html5rocks.com/en/tutorials/cors/),其中有更多关于服务器需要发送的确切头部的详细信息。