提问人:ateet 提问时间:7/19/2016 最后编辑:ateet 更新时间:1/6/2020 访问量:4690
发布带有 cors 的 JSON ajax 请求在 IE10/Edge 中不起作用
Post JSON ajax request with cors not working in IE10/Edge
问:
背景:-我创建了一个托管在本地系统 IIS 中的 WCF 服务。服务公开了 GET/POST 方法并启用了跨域,也可以使用 https 进行访问。为了使其可访问,使用了自签名证书。
测试:-当我尝试进行跨域ajax调用时,它在IE10 / Edge中对GET请求和POST请求(仅那些不接受数据作为json的post方法)工作正常。我能够在 chrome/Firebox 浏览器中对任何 GET/POST 请求进行跨域调用。只有IE 10 / Edge在ajax调用中传递contenttype:accept/json参数时导致对POST请求进行跨域调用的问题。
研究:-我阅读了很多博客/mdn,并了解了 IE 不虔诚地遵循 cors 的 cors 规范。我知道 cors 规范不会分配自定义标头/标头的值,因此 cors 预检中止。
我提出的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]
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的StartRequest事件中编写代码来处理选项请求:-
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 站点仅启用匿名身份验证,而禁用其他身份验证。即使我尝试使用有效的 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
请帮助我,因为我浏览了很多文章和博客,但仍然无法解决问题。 您的帮助将不胜感激!
专家请帮帮我!
答:
您可以在客户端检查以下几点:
- 您正在尝试覆盖 .这是(或曾经)是一个可读的属性,告诉您浏览器是否支持 CORS。(有关检查位置,请参阅 jQuery 源代码)
$.support.cors
- 根据 ajax 的 jQuery 文档,您可能希望添加到选项中
xhrFields: { withCredentials: true }
$.ajax()
- 使用 和 的正确大小写
dataType: "json"
charset=UTF-8
在服务器端,您可能希望尝试使用特定的主机名(回显标头)而不是响应标头中的通配符 () 进行响应。这在 MDN 中特别提到,在讨论 Access-Control-Allow-Credentials 的
段落中:Origin
*
Access-Control-Allow-Origin
重要说明:在响应凭据请求时,服务器必须指定域,并且不能使用通配符。如果标头通配符为:Access-Control-Allow-Origin: *,则上述示例将失败。
评论
Origin
http://
https://
http://www.google.com/
http://example.com/
http://example.com
https://example.com/
example.com
这不是一个长期的解决方案,但您可以查看 https://cors-anywhere.herokuapp.com/ 您可以通过此毫无问题地获取甚至 POST 数据。 在 URL 之前包含他们的链接,以便 https://cors-anywhere.herokuapp.com/http://ateet3371/Service1.svc/postdata 并将其设置为ajax中的URL值。就像我说的,这不是一个长期的解决方案,但如果它有效,那么看看你能从那里做些什么。
我希望我能提供更多帮助。祝你好运!
评论