How do I accept CORS AJAX requests on AppHarbor?

I'm using the Thinktecture.IdentityModel nuget package to enable CORS for WebAPI controllers in an MVC Web Application. At the moment, I'm only worried about POSTs but let me know about any problems with other verbs. This works when running through the IIS Express server.

When dealing with the AppHarbor deployment, it doesn't work. nginx doesn't seem to pass through the OPTIONS request to my code. What else is needed to get it running on AppHarbor?

Request

OPTIONS $path HTTP/1.1
Host: $servername Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://www.local
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17
Access-Control-Request-Headers: accept, origin, content-type
Accept: /
Referer: http://www.local/wordpress/2013/01/request-url-test/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en;q=0.8,en-US;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

Response

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 30 Jan 2013 02:34:14 GMT
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS, TRACE, GET, HEAD, POST
Public: OPTIONS, TRACE, GET, HEAD, POST

My web.config is set up with the following default handlers:

<handlers>
  <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.NETFrameworkv4.0.30319aspnet_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.NETFramework64v4.0.30319aspnet_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>

Is WebDAV to blame?

After the suggestion of Jeffery To, I disabled WebDAV by following these instructions. Didn't even know WebDAV was installed on AH, but doing this did change my results.

Relevant Web.config sections

<handlers>
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="WebDAV" />
  <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%Microsoft.NETFrameworkv4.0.30319aspnet_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.NETFramework64v4.0.30319aspnet_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>
<modules runAllManagedModulesForAllRequests="true">
  <remove name="WebDAVModule"/>
  <remove name="AspNetAppHarborIntegration" />
  <add name="AspNetAppHarborIntegration" type="Premotion.AspNet.AppHarbor.Integration.AppHarborModule, Premotion.AspNet.AppHarbor.Integration" />
</modules>

Request

OPTIONS $path HTTP/1.1
Host: $servername
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://www.local
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17
Access-Control-Request-Headers: accept, origin, content-type
Accept: /
Referer: http://www.local/wordpress/2013/01/request-url-test/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en;q=0.8,en-US;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

Response

HTTP/1.1 405 Method Not Allowed
Server: nginx
Date: Mon, 04 Feb 2013 17:09:19 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 76
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Expires: -1


WebDAV was to blame for the initial problem of not getting the full CORS headers in the response. The 405 error was a problem somewhere in the configuration of my app.

After some digging into the internals, it appears that the CORSMessageHandler for use with WebAPI (provided by Thinktecture) wasn't correctly identifying preflight requests and those requests were routed through to the WebAPI object itself.

I worked-around the issue by moving to the IIS module instead of the WebAPI one. This may make life more difficult in the future, but at least it works.


我可能在这里错过了一些东西,但是基于你包含的示例响应,似乎OPTIONS方法实际上已发送到您的应用程序 - AllowPublic标题包含在响应中。

链接地址: http://www.djcxy.com/p/42450.html

上一篇: 对预检请求的响应不会通过访问控制检查

下一篇: 我如何接受AppHarbor上的CORS AJAX请求?