我已经设置了一个从 MVC 4/Web API 模板开始的 ASP.NET Web 应用程序。似乎事情进展得很好——我不知道有什么问题。我使用 Chrome 和 Firefox 浏览该网站。我已经使用 Fiddler 进行了测试,所有的反应似乎都在赚钱。
所以现在我继续编写一个简单的 Test.aspx 来使用这个新的 Web API。脚本的相关部分:
<script type="text/javascript">
$(function () {
$.ajax({
url: "http://mywebapidomain.com/api/user",
type: "GET",
contentType: "json",
success: function (data) {
$.each(data, function (index, item) {
....
});
}
);
},
failure: function (result) {
alert(result.d);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("An error occurred, please try again. " + textStatus);
}
});
});
</script>
这会生成一个 REQUEST 标头:
OPTIONS http://host.mywebapidomain.com/api/user HTTP/1.1
Host: host.mywebapidomain.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://mywebapidomain.com
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type
Connection: keep-alive
照原样,Web API 返回 405 Method Not Allowed。
HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 30 Sep 2013 13:28:12 GMT
Content-Length: 96
<Error><Message>The requested resource does not support http method 'OPTIONS'.</Message></Error>
我知道 OPTIONS 动词默认情况下没有连接到 Web API 控制器中......所以,我将以下代码放在我的 UserController.cs 中:
// OPTIONS HTTP-verb handler
public HttpResponseMessage OptionsUser()
{
var response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
return response;
}
...这消除了 405 Method Not Allowed 错误,但响应完全为空 - 没有返回数据:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 30 Sep 2013 12:56:21 GMT
Content-Length: 0
必须有额外的逻辑......我不知道如何正确编码 Options 方法,或者控制器是否是放置代码的正确位置。奇怪(对我来说)Web API 站点在从 Firefox 或 Chrome 查看时会正确响应,但上面的 .ajax 调用会出错。如何处理 .ajax 代码中的“预检”检查?也许我应该在客户端的 .ajax 逻辑上解决这个问题?或者,如果这是由于未处理 OPTIONS 动词而导致的服务器端问题。
任何人都可以帮忙吗?这一定是一个非常普遍的问题,如果在这里得到回答,我深表歉意。我搜索但没有找到任何有帮助的答案。
更新 恕我直言,这是一个客户端问题,与上面的 Ajax JQuery 代码有关。我这样说是因为当我从 Web 浏览器访问 mywebapidomain/api/user 时,Fiddler 没有显示任何 405 错误标头。我可以复制这个问题的唯一地方是来自 JQuery .ajax() 调用。此外,上面相同的 Ajax 调用在服务器(相同域)上运行时也能正常工作。
我发现了另一篇文章:Prototype AJAX request being sent as OPTIONS 而不是 GET;导致似乎相关的 501 错误,但我已经修改了他们的建议但没有成功。显然,JQuery 是这样编码的,因此如果 Ajax 请求是跨域的(我的请求是跨域的),它会添加几个以某种方式触发 OPTIONS 标头的标头。
'X-Requested-With': 'XMLHttpRequest',
'X-Prototype-Version': Prototype.Version,
似乎应该有比在 JQuery 中修改核心代码更好的解决方案......
下面提供的答案假定这是一个服务器端问题。也许吧,我猜,但我倾向于客户,打电话给托管服务提供商也无济于事。