jquery - 使用 cors 发布 JSON ajax 请求在 IE10/Edge 中不起作用

标签 jquery ajax wcf cors iis-7.5

背景:- 我创建了一个托管在本地系统 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 规范不允许自定义 header / header 的值,因此 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" header 从请求中删除时返回正确的结果。

[OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "PostUrlData/{value}")]
    string PostUrlData(string value);

我已经在 WCF 的 Global.asax 中的 BeginRequest 事件中编写了代码来处理选项请求:-

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 中启用允许跨域调用设置,因为最终用户不会执行此类步骤。

陷入问题:-但仍然无法在 IE 10/Edge(已启用 cors)中执行 JSON 数据发布调用。

(已编辑)更新: 托管 WCF 的 IIS 站点仅启用匿名身份验证,而禁用其他身份验证。 即使我尝试使用有效的 https 证书,但它仍然不适用于 IE,但适用于 chrome。

请求 header

选项 https://service.domian.com/projectservice.svc/GetMultiListData HTTP/1.1 接受: */* 来源:https://sitename.servicedomain.com 访问控制请求方法:POST 访问控制请求 header :内容类型,接受 接受编码:gzip、deflate 用户代理:Mozilla/5.0(Windows NT 6.1;WOW64;Trident/7.0;rv:11.0),如 Gecko 主机:sitename.servicedomain.com 内容长度:0 连接:保持事件状态 缓存控制:无缓存

响应 header

HTTP/1.1 200 好 缓存控制:无缓存、无存储 服务器:微软-IIS/7.5 访问控制允许来源:sitename.servicedomain.com 访问控制允许方法:GET、POST、PUT、HEAD 访问控制允许凭据: true 访问控制允许 header :来源、内容类型、接受、X-Requested-With、 session 访问控制公开 header :DAV、内容长度、允许 访问控制最大年龄:1728000 X-Powered-By: ASP.NET 日期:2016 年 8 月 4 日星期四 17:26:27 GMT 内容长度:0

请帮助我,因为我浏览了很多文章和博客,但仍然无法解决问题。 我们将非常感谢您的帮助!

专家请帮助我!

最佳答案

您可以在客户端检查一些内容:

  • 您正在尝试覆盖$.support.cors。这是(或曾经)是一个可读属性,告诉您浏览器是否支持 CORS。 (请参阅 jQuery source 以了解检查位置)
  • 基于 jQuery docs for ajax您可能需要将 xhrFields: { withCredentials: true } 添加到 $.ajax() 选项
  • 使用正确的 dataType: "json"charset=UTF-8 大小写

在服务器端,您可能希望尝试使用特定主机名(回显 Origin header )而不是 Access- 中的通配符 (*) 进行响应Control-Allow-Origin 响应 header 。 MDN 中还讨论 Access-Control-Allow-Credentials 的段落中特别提到了这一点。 :

Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: *.

关于jquery - 使用 cors 发布 JSON ajax 请求在 IE10/Edge 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38451753/

相关文章:

javascript 错误为 null 或不是对象

ajax - JSF 2.2 - 文件上传不适用于 Ajax。表单似乎具有不正确的编码类型(仅通过 AJAX)

c# - RESTful WCF Web 服务的 UriTemplate 前缀

javascript - 在 Node.js/Express 中为 Sequelize.Create 触发两次 Ajax POST 请求

c# - 生成的 WCF 代理配置使用服务器的本地名称

.net - WCF 扩展身份验证

javascript - 从右向左滑动

javascript - jQuery .val() 方法只给我第一个输入的值

javascript - 检测溢出是否在元素上起作用

php - 使用 JQuery 和 Ajax 进行动态相关选择