我有一个在我的本地IIS实例上运行的ASP.NET Web API应用程序。 Web应用程序配置了CORS。我调用的Web API方法类似于:
[POST("/API/{foo}/{bar}")]
public String DoSomething(String foo, String bar)
{
return "Hello, World!";
}
客户端,我正在运行以下请求:
$.ajax({
url: "http://machine/API/Foo/Bar",
type: "POST",
success: function (data) {
console.log("Success: " + data);
},
error: function (xhr, status, message) {
console.log("Failure: " + status + ", " + message);
}
});
Firefox 15.0.1中的相应控制台日志读作:
test.html (line 38)
POST http://machine/API/Foo/Bar
200 OK
112ms
jquery-1.7.2.js (line 8240)
Success: "Hello, World!"
当我访问本地IIS服务器时以及在Visual Studio中访问IIS Express开发实例的相应URL时,这可以完美地工作。
当我添加单个请求标头时,任何内容,当针对我的本地IIS服务器时,以下请求失败:
$.ajax({
url: "http://machine/API/Foo/Bar",
type: "POST",
onBeforeSend: function (xhr, settings) {
xhr.setRequestHeader("A", "B");
},
success: function (data) {
console.log("Success: " + data);
},
error: function (xhr, status, message) {
console.log("Failure: " + status + ", " + message);
}
});
我看到的那么详细的日志消息是:
Failure: error,
在针对Visual Studio中的IIS Express开发实例时,相同的POST
请求成功。
在Fiddler中,无论我是否在Visual Studio中定位完整的IIS服务器或IIS Express,前两个请求都会顺利通过:
// Request
POST http://machine/Foo/Bar HTTP/1.1
Host: machine
Content-Length: 0
// Response
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 38
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 09 Oct 2012 20:16:29 GMT
"Hello, World!"
排列{With Headers, Without Headers} x {Full IIS, IIS Express}
在Fiddler中都产生相同的输出。
简而言之:为什么设置请求标头导致AJAX调用对我本地完全成熟的IIS实例失败?
此外,为什么我的请求在Fiddler中成功但在我的Javascript代码中没有成功?如果我无法在适当的IIS实例中设置请求标头,那么这是一个严重的破坏。
答案 0 :(得分:1)
这可能与跨源资源共享有关。在最近的一个项目中,我们遇到了类似的问题,并且使用自定义http标头进行跨域资源共享已成为问题所在。
只有当javascript的域不同而不是正在进行的ajax调用的域时,才会发生这种情况。
要确定是否是这种情况,您可以尝试在Global.asax中添加类似的内容:
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS" )
{
//These headers will handle the HTTP OPTIONS call sent by the browser
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods" , "GET, POST" );
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "A, Foo, Bar");
HttpContext.Current.Response.End();
}
}
注意警惕做这样的事情。将Access-Control-Allow-Origin标头设置为值“*”是一种安全风险。
答案 1 :(得分:0)
我的CORS问题的实际根本问题与IIS 7使用的管道有关。
当IIS 7在经典管道下运行时,请求未被OPTIONS
请求预检。正如我在问题中描述的那样,他们会默默地失败。我在Firebug的Net选项卡中看到了这一点,并通过交互式调试将Thinktecture IdentityModel库明确包含在我的解决方案的项目中。
但是,当IIS 7在Integrated Pipeline下运行时,CORS受到尊重。带有自定义标头的POST
个请求和请求已正确预检。