在旧的chrome版本中,我可以使用jquery ajax向wcf rest服务发布请求,虽然它们不是同一个域,但我在服务器上添加了CORS支持,在我更新到30.0.1599.101版本之后,它再次无效。我用rest客户端,safari,IE和firefox测试,他们可以工作。此外,仍支持Get请求。 代码段如下,
function getTempValue(pointname, succeed) {
var data = '{"pointname":"' + pointname + '"}';
var invoker = new InterfaceInvoker("http://localhost/UCBService/UCBDemoService.svc", "GetPointValue", data, "POST");
invoker.Invoke(succeed);
}
function InterfaceInvoker(newUrl, newInterfaceName, newParameter, newRequestType) {
var url, interfaceName, parameter, requestType;
this.GetUrl = function () {
return url;
};
this.SetUrl = function (newUrl) {
url = newUrl || "no url setted";
};
this.GetInterfaceName = function () {
return interfaceName;
};
this.SetInterfaceName = function (newInterfaceName) {
interfaceName = newInterfaceName || "no interface setted";
};
this.GetParameter = function () {
return parameter;
};
this.SetParameter = function (newParameter) {
parameter = newParameter;
};
this.GetRequestType = function () {
return requestType;
};
this.SetRequestType = function (newRequestType) {
requestType = newRequestType || "no requestType setted";
};
this.SetUrl(newUrl);
this.SetInterfaceName(newInterfaceName);
this.SetParameter(newParameter);
this.SetRequestType(newRequestType);
}
InterfaceInvoker.prototype.Invoke = function (successCallBack, failureCallback) {
var Type = this.GetRequestType(),
Url = this.GetUrl() + "/" + this.GetInterfaceName(),
Data = this.GetParameter(),
ContentType = "application/json; charset=utf-8",
DataType = "json",
ProcessData = true;
$.support.cors = true;
return $.ajax({
type: Type,
async: "true",
url: Url, // Location of the service
data: Data, //Data sent to server
contentType: ContentType, // content type sent to server
dataType: DataType, //Expected data format from server
processdata: ProcessData, //True or False
timeout: 3000000, //Timeout setting
success: successCallBack || function () { alert("Succeded!") }, //On Successfull service call
error: failureCallback || function (jqXHR, textStatus, errorThrown) {
alert("Failed!" + jqXHR.statusText); } // When Service call fails
});
};
回复信息如下,
Request URL:http://localhost/UCBService/UCBDemoService.svc/GetPointValue)
Request Method:OPTIONS
Status Code:405 Method Not Allowed
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost
Origin:http://localhost:51818
Referer:
http://localhost:51818/HTMLPage1.htm
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
Response Headers
Access-Control-Allow-Headers:Accept, content-type
Access-Control-Allow-Methods:POST, GET, OPTIONS, DELETE, PUT
Access-Control-Allow-Origin:*
Allow:POST
Cache-Control:private
Content-Length:1565
Content-Type:text/html; charset=UTF-8
Date:Wed, 23 Oct 2013 08:01:23 GMT
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
谢谢,
答案 0 :(得分:0)
也不太确定解决方案(在搜索我的问题的解决方案时偶然发现了你的问题:D),但我找到了链接(http://praneeth4victory.wordpress.com/2011/09/29/405-method-not-allowed/),这让我想到OPTIONS-Preflight-Request在新的Chrome版本中不再是可选的,但必须使用。我会尝试实现OPTIONS-Request的答案,看看是否有帮助。
编辑: 是的,事实证明这是问题所在。我添加了
if request.method == "OPTIONS":
response = Response()
response.headers.add("Access-Control-Allow-Methods", "GET,POST,PUT,DEL")
response.headers.add('Access-Control-Allow-Origin', "*")
response.headers.add('Access-Control-Allow-Credentials', 'true')
response.headers.add('Access-Control-Allow-Headers', 'Authorization')
return response
对于我的请求处理方法(仅用于测试,这肯定可以更好地完成:D)并且jQuery不再抱怨。
答案 1 :(得分:0)
我在帮助朋友时最近遇到了同样的错误。问题是Chrome错误地忽略了失败的转机前请求。这个bug起源于webkit。但是,您遇到的问题与使用.net 4.0的IIS 7在飞行前OPTIONS调用上发送405有关。解决此问题的方法是编写自己的OPTIONS请求处理程序。 这篇博客文章很好地解释了它。 http://evolpin.wordpress.com/2012/10/12/the-cors/
直接从帖子中获取:
首先,您需要创建一个拦截OPTIONS并允许它们始终成功的类 公共类CORSModule:IHttpModule { public void Dispose(){}
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += delegate
{
if (context.Request.HttpMethod == "OPTIONS")
{
var response = context.Response;
response.StatusCode = (int)HttpStatusCode.OK;
}
};
}
}
然后你需要修改你的web.config
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type,Authorization" />
</customHeaders>
</httpProtocol>
<modules>
<add name="CORSModule" type="CORSModule" />
</modules>
</system.webServer>
这将拦截OPTIONS请求并返回200.请注意,它不安全,您应该添加适当的安全性。作为最后一点,升级到.net 4.5被认为是最好的解决方案。