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…)?
对于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
如果你正在使用Jersey的REST API,你可以这样做
你不需要改变你的webservices实现。
我会解释Jersey 2.x
1)首先添加一个ResponseFilter,如下所示
import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
public class CorsResponseFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
responseContext.getHeaders().add("Access-Control-Allow-Origin","*");
responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
}
}
2)然后在web.xml中,在jersey servlet声明中添加如下内容
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>YOUR PACKAGE.CorsResponseFilter</param-value>
</init-param>
以下是我在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,它会自动添加相关的头信息。希望这能帮助有类似情况的人。