我在让 jquery 将一些 json 数据发布到我在 WCF 服务上使用的休息方法时遇到了一些麻烦。
在 WCF 方面,这是操作合同:
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "PostSomething")]
MyResult PostSomething(MyRequest request);
两者MyResult
都MyRequest
标有所有必要的DataContract
和DataMember
属性,并且服务正在公开 WebHttp 端点。
在 JQuery 方面,这是我的函数调用:
var jsonStr = JSON.stringify(reqObj);
$.ajax({
type: "POST",
dataType: "json",
url: "http://localhost/MyService/PostSomething",
contentType: "application/json; charset=utf-8",
data: jsonStr,
success: function (html) {
alert(html);
}
});
这个请求永远不会到达我的方法(我每次都得到一个 405 Method Not Allowed),并且在 Charles 中查看请求看起来像这样:
OPTIONS /MyService/PostSomething HTTP/1.1
Host: localhost
Cache-Control: max-age=0
Access-Control-Request-Method: POST
Origin: null
Access-Control-Request-Headers: Content-Type, Accept
Accept: */*
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
一些奇怪的事情:
- 该方法是 OPTIONS 而不是 POST
- 内容类型(在另一个选项卡中)显示
text/html; charset=UTF-8
而不是 json - JSON数据无处可见
但是,如果我在 Charles 中修改请求,使其标头与此处的解决方案相似,那么一切正常:
POST /MyService/PostSomething HTTP/1.1
Content-Type: application/json; charset=utf-8
Host: localhost
Content-Length: 152
{"Id":"", "Name":"testspot","Description":"test" }
在这里查看教程和其他问题,其他人设法让 JQuery 发布到这样的 WCF REST 方法,我不知道我在这里做错了什么。
哦,举个例子,这是一个 WCF 4 服务,我使用的是 JQuery 1.4.4。
谢谢,
更新:
在阅读了更多内容并感谢 Darrel 将我指向跨域规范之后,我设法通过在服务接口上对我的服务进行一些小的更改来进一步了解:
[OperationContract]
[WebInvoke(Method = "*",
BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "PostSomething")]
MyResult PostSomething(MyRequest request);
在实现中,我需要检查传入的请求是否针对 OPTIONS 并在这种情况下返回一些标头而不是执行预期的工作:
if (WebOperationContext.Current.IncomingRequest.Method == "OPTIONS")
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept");
return null;
}
然后该方法被调用两次,第一次服务器返回 null 但向客户端添加一些标头,然后使用 POST 作为方法发出实际请求,服务器继续正常处理请求。