发布JSON ajax请求,其中cors无法在IE10/Edge中运行

ate*_*eet 14 ajax wcf jquery iis-7.5 cors

背景: -我创建了一个托管在本地系统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 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);
            }
        });
Run Code Online (Sandbox Code Playgroud)

如果我删除contentType: "application/json; charset=utf-8"然后它抛出错误的请求错误,否则它抛出访问被拒绝错误.

WCF中的方法实现是: -

[OperationContract]
    [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "PostResponseData")]
    string PostResponseData(PostDataTest postDT);
Run Code Online (Sandbox Code Playgroud)

而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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我使用方法PostUrl数据然后成功执行ajax调用并返回正确的结果,如果ContentType:"Application/json"标头从请求中删除.

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

我已经在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();
        } 
Run Code Online (Sandbox Code Playgroud)

我无法Allow cross domain call在IE中启用设置,因为最终用户不会执行此类步骤.

陷入困境: -但仍然无法在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

请通过大量文章和博客帮助我,但仍无法解决问题.对你的帮助表示感谢!

请专家帮助我!

sea*_*lea 0

您可以在客户端检查以下几项内容:

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

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

重要提示:响应凭据请求时,服务器必须指定域,并且不能使用通配符。如果标头使用通配符为:Access-Control-Allow-Origin: *,则上述示例将失败。