【问题标题】:new chrome version issue in cross domain request using ajax使用 ajax 的跨域请求中的新 chrome 版本问题
【发布时间】:2013-11-02 17:12:55
【问题描述】:

在旧的 chrome 版本中,我可以使用 jquery ajax 向 wcf rest 服务发布请求,尽管它们不是同一个域,我将 CORS 支持添加到服务器,在我更新到 30.0.1599.101 版本后,它不再工作了。我用 rest 客户端、safari、IE 和 firefox 测试,它们可以工作。此外,仍然支持获取请求。 代码sn-p如下,

function getTempValue(pointname, succeed) {

        var data = '{"pointname":"' + pointname + '"}';
        var invoker = new InterfaceInvoker("http://localhost/UCBService/UCBDemoService.svc", "GetPointValue", data, "POST");
        invoker.Invoke(succeed);
    }
function InterfaceInvoker(newUrl, newInterfaceName, newParameter, newRequestType) {
    var url, interfaceName, parameter, requestType;
    this.GetUrl = function () {
    return url;
};
this.SetUrl = function (newUrl) {
    url = newUrl || "no url setted";
};
this.GetInterfaceName = function () {
    return interfaceName;
};
this.SetInterfaceName = function (newInterfaceName) {
    interfaceName = newInterfaceName || "no interface setted";
};
this.GetParameter = function () {
    return parameter;
};
this.SetParameter = function (newParameter) {
    parameter = newParameter;
};
this.GetRequestType = function () {
    return requestType;
};
this.SetRequestType = function (newRequestType) {
    requestType = newRequestType || "no requestType setted";
};
this.SetUrl(newUrl);
this.SetInterfaceName(newInterfaceName);
this.SetParameter(newParameter);
this.SetRequestType(newRequestType);
}
InterfaceInvoker.prototype.Invoke = function (successCallBack, failureCallback) {
    var Type = this.GetRequestType(),
        Url = this.GetUrl() + "/" + this.GetInterfaceName(),
        Data = this.GetParameter(),       
        ContentType = "application/json; charset=utf-8",
        DataType = "json",
        ProcessData = true;
    $.support.cors = true;
 return $.ajax({
 type: Type,
 async: "true",      
        url: Url,                       // Location of the service
        data: Data,                     //Data sent to server
        contentType: ContentType,       // content type sent to server
        dataType: DataType,             //Expected data format from server
        processdata: ProcessData,       //True or False
        timeout: 3000000,                //Timeout setting 
        success: successCallBack || function () { alert("Succeded!") }, //On Successfull service call
        error: failureCallback || function (jqXHR, textStatus, errorThrown) { 
        alert("Failed!" + jqXHR.statusText); }      // When Service call fails
    });
};

回复信息如下,

Request URL:http://localhost/UCBService/UCBDemoService.svc/GetPointValue)
Request Method:OPTIONS
Status Code:405 Method Not Allowed
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost
Origin:http://localhost:51818
Referer:
    http://localhost:51818/HTMLPage1.htm
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko)       Chrome/30.0.1599.101 Safari/537.36


Response Headers
Access-Control-Allow-Headers:Accept, content-type
Access-Control-Allow-Methods:POST, GET, OPTIONS, DELETE, PUT
Access-Control-Allow-Origin:*
Allow:POST
Cache-Control:private
Content-Length:1565
Content-Type:text/html; charset=UTF-8
Date:Wed, 23 Oct 2013 08:01:23 GMT
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET

谢谢,

【问题讨论】:

    标签: google-chrome jquery post cross-domain


    【解决方案1】:

    我最近在帮助朋友时遇到了同样的错误。问题是 Chrome 错误地忽略了失败的飞行前请求。这个错误起源于 webkit。但是,您遇到的问题与 IIS 7 和 .net 4.0 在飞行前 OPTIONS 调用上发送 405 有关。解决此问题的方法是编写您自己的 OPTIONS 请求处理程序。 这个博客条目很好地解释了它。 http://evolpin.wordpress.com/2012/10/12/the-cors/

    直接取自帖子:

    首先,您需要创建一个类来拦截 OPTIONS 并允许它们始终成功 公共类CORSModule:IHttpModule { 公共无效处置(){}

        public void Init(HttpApplication context)
        {
            context.PreSendRequestHeaders += delegate
            {
                if (context.Request.HttpMethod == "OPTIONS")
                {
                    var response = context.Response;
                    response.StatusCode = (int)HttpStatusCode.OK;
                }
            };
        }
    }
    

    那你需要修改你的web.config

    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" />
          <add name="Access-Control-Allow-Origin" value="*" />
          <add name="Access-Control-Allow-Headers" value="Content-Type,Authorization" />
        </customHeaders>
      </httpProtocol>
      <modules>
        <add name="CORSModule" type="CORSModule" />
      </modules>
    </system.webServer>
    

    这将拦截 OPTIONS 请求并返回 200。请注意,它不安全,您应该添加适当的安全性。最后一点,升级到 .net 4.5 被认为是最好的解决方案。

    【讨论】:

      【解决方案2】:

      也不太确定解决方案(在为我的问题寻找解决方案时偶然发现了您的问题 :D),但我找到了链接 (http://praneeth4victory.wordpress.com/2011/09/29/405-method-not-allowed/),这让我认为 OPTIONS-Preflight-Request 不是在新的 Chrome 版本中不再是可选的,但必须的。我会尝试实现对 OPTIONS-Request 的回答,看看是否有帮助。

      编辑: 是的,事实证明这是问题所在。我加了

      if request.method == "OPTIONS":
          response = Response()
          response.headers.add("Access-Control-Allow-Methods", "GET,POST,PUT,DEL")
          response.headers.add('Access-Control-Allow-Origin', "*")
          response.headers.add('Access-Control-Allow-Credentials', 'true')
          response.headers.add('Access-Control-Allow-Headers', 'Authorization')
          return response
      

      对于我的请求处理方法(只是为了测试,这肯定可以做得更好:D)并且 jQuery 不再抱怨。

      【讨论】:

        猜你喜欢
        • 2023-04-04
        • 1970-01-01
        • 2012-02-20
        • 2013-11-09
        • 1970-01-01
        • 1970-01-01
        • 2010-10-13
        • 2014-09-08
        • 1970-01-01
        相关资源
        最近更新 更多