发布JSON ajax请求与cors无法在IE10 / Edge中工作
背景: –我创建了一个托管在本地系统IIS中的WCF服务。 服务公开GET / POST方法和跨域启用,也可以使用https访问。 要使其可访问,请使用自签名证书。
测试: –当我尝试进行跨域ajax调用时,它可以正常用于GET请求和POST请求(只有那些不接受数据作为json的post方法)在IE10 / Edge中。 我可以在chrome / Firebox浏览器中为任何GET / POST请求进行跨域调用。 只有IE 10 / Edge会导致在ajax调用中传递contenttype:accept / json参数时对POST请求进行跨域调用的问题。
研究: –我阅读了很多博客/ mdn,并了解了其中IE不虔诚地追随cors的cors的规范。 我知道cors规范并没有提供自定义标题/标题的值,因为cors preflight已中止。
我正在制作的ajax请求示例: –
var postDT = { "postValue": "test" }; debugger; $.support.cors = true; $.ajax({ type: "POST", data: JSON.stringify(postDT), url: "http://ateet3371/Service1.svc/postdata", contentType: "application/json; charset=utf-8", dataType: "JSON", processData: true, success: function (data) { alert(data); }, error: function (jqXHR, textStatus, errorThrown) { var a = jqXHR; alert(jqXHR + '---' + textStatus + '---' + errorThrown); } });
如果我删除了contentType: "application/json; charset=utf-8"
那么它会抛出错误的请求错误,否则会抛出拒绝访问错误。
WCF中的方法实现是: –
[OperationContract] [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "PostResponseData")] string PostResponseData(PostDataTest postDT);
而datacontract是: –
[DataContract] public class PostDataTest { private string post_value; // Apply the DataMemberAttribute to the property. [DataMember] public string postValue { get { return post_value; } set { post_value = value; } } }
如果我使用方法PostUrl数据然后成功执行ajax调用并返回正确的结果如果ContentType:“Application / json”标头从请求中删除。
[OperationContract] [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "PostUrlData/{value}")] string PostUrlData(string value);
我已经在WCF的Global.asax中的BeginRequest事件中编写代码来处理Options请求: –
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); if (HttpContext.Current.Request.HttpMethod == "OPTIONS" ) { //These headers are handling the "pre-flight" OPTIONS call sent by the browser HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, HEAD"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, X-Requested-With, Session"); HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "DAV, content-length, Allow" ); HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000" ); HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache,no-store"); HttpContext.Current.Response.End(); }
并且我无法在IE中启用Allow cross domain call
设置,因为最终用户不会执行此类步骤。
陷入困境: –但仍然无法在IE 10 / Edge(已启用cors)中进行JSON数据调用。
(已编辑)更新:托管WCF的IIS站点仅启用了匿名身份validation,同时禁用了其他身份validation。 即使我尝试使用https的有效证书,但它仍然不适用于IE,但适用于chrome。
请求标题
OPTIONS https://service.domian.com/projectservice.svc/GetMultiListData HTTP/1.1 Accept: */* Origin: https://sitename.servicedomain.com Access-Control-Request-Method: POST Access-Control-Request-Headers: content-type, accept Accept-Encoding: gzip, deflate User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko Host: sitename.servicedomain.com Content-Length: 0 Connection: Keep-Alive Cache-Control: no-cache
响应标题
HTTP/1.1 200 OK Cache-Control: no-cache,no-store Server: Microsoft-IIS/7.5 Access-Control-Allow-Origin: sitename.servicedomain.com Access-Control-Allow-Methods: GET,POST,PUT,HEAD Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: Origin,Content-Type,Accept,X-Requested-With,Session Access-Control-Expose-Headers: DAV,content-length,Allow Access-Control-Max-Age: 1728000 X-Powered-By: ASP.NET Date: Thu, 04 Aug 2016 17:26:27 GMT Content-Length: 0
请帮助我,因为我经历了大量的文章和博客,仍然无法解决问题。 对你的帮助表示感谢!
请专家帮助我!
您可以检查客户端的一些事项:
- 你试图覆盖
$.support.cors
。 这是(或曾经)意味着是一个可读属性,告诉您浏览器是否支持CORS。 (请参阅jQuery源以了解其中的位置) - 基于ajax的jQuery文档,您可能希望将
xhrFields: { withCredentials: true }
到$.ajax()
选项中 - 使用正确的
dataType: "json"
shelldataType: "json"
和charset=UTF-8
在服务器端,您可能希望尝试使用特定主机名(回显Origin
标头)而不是Access-Control-Allow-Origin
响应标头中的通配符( *
)进行响应。 MDN在一个段落中也特别提到了这一点,还讨论了Access-Control-Allow-Credentials
:
重要说明:在响应凭证请求时,服务器必须指定域,并且不能使用通配符。 如果标头被通配为:Access-Control-Allow-Origin:*,则上面的示例将失败。