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…)?
在pkozlowski的评论中有完美的描述。
我有工作解决方案与AngularJS 1.2.6和ASP。NET Web Api,但当我将AngularJS升级到1.3.3时,请求失败。
Solution for Web Api server was to add handling of the OPTIONS requests at the beginning of configuration method (more info in this blog post):
app.Use(async (context, next) =>
{
IOwinRequest req = context.Request;
IOwinResponse res = context.Response;
if (req.Path.StartsWithSegments(new PathString("/Token")))
{
var origin = req.Headers.Get("Origin");
if (!string.IsNullOrEmpty(origin))
{
res.Headers.Set("Access-Control-Allow-Origin", origin);
}
if (req.Method == "OPTIONS")
{
res.StatusCode = 200;
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Methods", "GET", "POST");
res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Headers", "authorization", "content-type");
return;
}
}
await next();
});
我放弃了解决这个问题。
我的IIS网络。config中有相关的“Access-Control-Allow-Methods”,我尝试在我的Angular代码中添加配置设置,但在花了几个小时试图让Chrome调用一个跨域JSON web服务后,我悲惨地放弃了。
最后,我添加了一个愚蠢的ASP。Net handler网页,让它调用JSON web服务,并返回结果。它在两分钟内就运行起来了。
下面是我使用的代码:
public class LoadJSONData : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string URL = "......";
using (var client = new HttpClient())
{
// New code:
client.BaseAddress = new Uri(URL);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", "Basic AUTHORIZATION_STRING");
HttpResponseMessage response = client.GetAsync(URL).Result;
if (response.IsSuccessStatusCode)
{
var content = response.Content.ReadAsStringAsync().Result;
context.Response.Write("Success: " + content);
}
else
{
context.Response.Write(response.StatusCode + " : Message - " + response.ReasonPhrase);
}
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
在我的Angular控制器中…
$http.get("/Handlers/LoadJSONData.ashx")
.success(function (data) {
....
});
我相信有一种更简单/更通用的方式来做这件事,但生命太短暂了…
这对我很有效,现在我可以继续做正常的工作了!!
如果你正在使用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>
来的有点晚了
如果你正在使用Angular 7(或5/6/7)和PHP作为API,并且仍然得到这个错误,尝试在端点(PHP API)中添加以下头选项。
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT, GET, POST, PUT, OPTIONS, DELETE, PATCH");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization");
注意:只需要Access-Control-Allow-Methods。但是,我在这里粘贴了另外两个Access-Control-Allow-Origin和Access-Control-Allow-Headers,只是因为你需要正确地设置所有这些,以便Angular应用能够正确地与你的API对话。
希望这能帮助到一些人。
欢呼。
以下是我在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