场景:我想在这里做正确的事情。我添加CORS功能到我的REST服务(ASP.NET Web-API)依赖于Thinktecture Identitymodel CORS DelegatingHandler。到现在为止还挺好。
要实际测试它是否工作,我做了以下:
>我设置了一个简单的HTML页面,并将其发布在与其他服务不同的主机上(xttp:// otherhost / simplewebpage)。该页面使用JQuery发出样本请求。代码见下文。
>下一步我设置了我的休息服务,不使用iis express,而是在我的开发机器上运行它的完全吹的实例(xttp:// developmenthost / restservice)。
>最后但并非最不重要的是,在我的开发机器上,我打开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,POST Date: Fri,15 Feb 2013 14:09:27 GMT Content-Length: 0
这当然不是接近预期的反应。有趣的部分是,请求甚至没有打我的应用程序中的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 }); }
生成的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
…你已经看到了对上述的反应。
完全回答我的OPTIONS请求的任何想法?还是我的JQuery代码有缺陷?
如果我使用例如Postman(谷歌Chrome应用程序)或如果我在Fiddler伪造请求(这可能是因为他们没有做CORS协商 – 没有OPTIONS请求),REST服务工作正常。
更新#1:今天早些时候我读到某个地方禁用WebDAV是强制性的,因为它干扰OPTIONS请求。我的IIS角色服务视图告诉我WebDAV发布未安装。
*更新#2:*问题解决?我挖得更深。有一个在IIS中注册的模块负责对“OPTIONS”请求的“不需要的(?)”响应。它的名称是“OPTIONSVerbHandler”(handler: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,authorization X-AspNet-Version: 4.0.30319 Date: Fri,15 Feb 2013 15:09:25 GMT Content-Length: 0
一旦你知道问题在哪里,当然你会发现大量的资源,告诉你,以确保你的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,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,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,bitness64" responseBufferLimit="0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer>
它不工作在IE9虽然(“错误:没有运输”)。如果有人像我一样走在同一条路上 – >它是一个IE9的事情:http://stackoverflow.com/a/10232313/1407618