JQuery坚持CORS预检和IIS幽灵响应

lap*_*sus 33 jquery http cors asp.net-web-api

我被卡住了. 说真的...... - 解决了.请继续阅读:)

场景:我想在这里做正确的事情.我依靠Thinktecture Identitymodel CORS DelegatingHandler将CORS功能添加到我的REST服务(ASP.NET Web-API).到现在为止还挺好.

为了实际测试它是否正常工作,我做了以下事情:

  1. 我设置了一个简单的HTML页面,并将其发布在与其他服务不同的主机上(xttp:// otherhost/simplewebpage).该页面使用JQuery来发出样本请求.代码见下文.
  2. 接下来,我将我的休息服务设置为不使用iis express,而是在我的开发机器上运行它的完整实例(xttp:// developmenthost/restservice).
  3. 最后但并非最不重要的是在我的开发机器上,我打开了xttp:// otherhost/simplewebpage并触发了Ajax请求.执行错误回调告诉我Chrome中存在"传输错误"(IE9)或""(空字符串).我确保没有代理相关的连接问题或类似的东西.

所以我出去看了Fiddler跟踪和IIS日志.Fiddler说没有GET/rest/hello请求,而是一个OPTIONS/rest/hello请求 - 这完全没问题且预期!但是对OPTIONS请求的响应相当有趣!

整个响应头看起来像这样:

HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/7.5
Public: OPTIONS, TRACE, GET, HEAD, POST
Date: Fri, 15 Feb 2013 14:09:27 GMT
Content-Length: 0
Run Code Online (Sandbox Code Playgroud)

这当然远不及预期的反应.有趣的是,请求甚至没有在我的应用程序中命中Application_BeginRequest().所以我的应用程序无法对该结果负责.我可以在我的IIS日志中看到请求,IIS添加了Powered-by-ASP.NET标头..因此它肯定会通过(右侧)IIS站点.

触发ajax请求的JQuery代码:

    function Run()
    {
        $.ajax({
            type: 'GET',
            url: url,
            dataType: "json",
            beforeSend: function(jqXhr) {
                jqXhr.setRequestHeader("Authorization", "Basic " + getBasicHttpEncodedString(userName, password));
                jqXhr.setRequestHeader("Api-Key", "123");
            },
            success: successCallback,
            error: errorCallback,
            timeout: 180*1000
        });
    }
Run Code Online (Sandbox Code Playgroud)

生成的OPTIONS请求如下所示:

OPTIONS http://services.dev13/Rest/Hello HTTP/1.1
Host: developmenthost
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://otherhost/simplewebpage
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17
Access-Control-Request-Headers: accept, origin, api-key, authorization
Accept: */*
DNT: 1
Referer: http://otherhost/simplewebpage
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Run Code Online (Sandbox Code Playgroud)

......你已经看到了对上面的反应.

知道谁准确回答我的OPTIONS请求?或者我的JQuery代码有缺陷吗?如果我使用例如Postman(谷歌Chrome应用程序)或者如果我在Fiddler中伪造请求(这可能是因为他们不进行CORS协商 - 没有OPTIONS请求),REST服务就可以正常工作.

更新#1:今天早些时候,我在某处读到禁用WebDAV是强制性的,因为它会干扰OPTIONS请求.我的IIS角色服务视图告诉我未安装 WebDAV Publishing.

*更新#2:*问题解决了?我深入挖掘.在IIS中注册了一个模块,负责对OPTIONS请求的"不期望的(?)"响应.它的名字是"OPTIONSVerbHandler"(处理程序:ProtocolSupportModule).如果我禁用该模块,请求将传递到我的应用程序.创建了一个更有意义的响应,然后是实际的GET请求! 好极了!

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: http://otherhost/simplewebpage
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept,origin,api-key,authorization
X-AspNet-Version: 4.0.30319
Date: Fri, 15 Feb 2013 15:09:25 GMT
Content-Length: 0
Run Code Online (Sandbox Code Playgroud)

一旦你知道问题出在哪里,你当然会发现很多资源告诉你要确保你的web.config看起来像这样: - /

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="false">
      <remove name="WebDAVModule" />
    </modules>
    <handlers>
      <remove name="OPTIONSVerbHandler" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
Run Code Online (Sandbox Code Playgroud)

它仍然不能在IE9中工作("错误:没有传输").如果有人和我一样走上了同样的道路 - >这是IE9的事情:https://stackoverflow.com/a/10232313/1407618

Luk*_*uke 1

您的答案在这里: https: //gist.github.com/mathieucarbou/1114981

基本上,IE 对 cors 有一些非常具体的警告和陷阱。我曾经开始自己写一个,但后来我找到了 mathieucarbou 的解决方案,并认为他的更好。

这可能是一个比您想要的更重的解决方案,但对于跨浏览器支持,我发现尽可能使用“自定义解决方案”来攻击 IE 是可以接受的。