Preflight Options 检查 Azure 中的选项?

Preflight Options check options in Azure?

我正在构建一个简单的 ServiceStack 应用程序并打算将其托管在 AzureWebSites 上。那工作正常。我需要 CORS 才能使应用程序运行。在本地 IIS Express 和 IIS 7.5 中,这工作正常 - 但在 Azure 或 AppHarbor 上不行。

实际的 AJAX GET 和 POST 请求工作正常,问题是 pre-flight OPTIONS 检查 return 一个空响应;没有 headers,没有。

代码在 GitHub。您可以在 git 提交历史中看到我尝试过的一些东西。

我已经启用了失败请求记录——但这没有帮助。我没有收到 400+ 系列错误代码 - 我根本没有收到任何回复。

编辑:感谢@paaschpa,我已经开始从不同的机器上寻找问题。添加了来自 Linux 机器的另一个响应。它表明 cURL 正在返回一些奇怪的东西(见下文)导致它根据这个 SO 问题输出调试: Why is cURL returning "additional stuff not fine"?

当我从我的 Rackspace Linux 机器测试 Azure 时,我得到这个:

kyleh@media:~$ curl -X curl -X OPTIONS -H "Origin: http://www.example.com" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: X-Requested-With" --verbose http://sstodo.azurewebsites.net/items
* About to connect() to sstodo.azurewebsites.net port 80 (#0)
*   Trying 23.101.118.145...
* connected
* Connected to sstodo.azurewebsites.net (23.101.118.145) port 80 (#0)
> OPTIONS /items HTTP/1.1
> User-Agent: curl/7.21.0 (x86_64-pc-linux-gnu) libcurl/7.26.0 OpenSSL/1.0.1e zlib/1.2.3.4 libidn/1.25 libssh2/1.4.2 librtmp/2.3
> Host: sstodo.azurewebsites.net
> Accept: */*
> Origin: http://www.example.com
> Access-Control-Request-Method: POST
> Access-Control-Request-Headers: X-Requested-With
> 
* additional stuff not fine transfer.c:1037: 0 0
* additional stuff not fine transfer.c:1037: 0 0
* additional stuff not fine transfer.c:1037: 0 0
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200 OK
< Cache-Control: private
< Content-Length: 0
< Vary: Accept
< Server: Microsoft-IIS/8.0
< X-Powered-By: ServiceStack/4.036 Win32NT/.NET
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
< Access-Control-Allow-Headers: Content-Type
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Set-Cookie: ARRAffinity=f1d67e2939c9eab291aa7a92c2c5cffe872dc89340409c771374fbf6bc961bd3;Path=/;Domain=sstodo.azurewebsites.net
< Date: Sun, 01 Feb 2015 02:57:55 GMT
< 
* Connection #0 to host sstodo.azurewebsites.net left intact
* Closing connection #0

当我在本地测试站点时,结果 looks right。这是本地结果 (VS / IIS Express):

curl -X OPTIONS 
 -H "Origin: http://www.example.com" 
 -H "Access-Control-Request-Method: POST" 
 -H "Access-Control-Request-Headers: X-Requested-With"
 --verbose http://localhost:1061/items
* timeout on name lookup is not supported
* About to connect() to localhost port 1061 (#0)
*   Trying 127.0.0.1...
* connected
* Connected to localhost (127.0.0.1) port 1061 (#0)
> OPTIONS /items HTTP/1.1
> User-Agent: curl/7.26.0
> Host: localhost:1061
> Accept: */*
> Origin: http://www.example.com
> Access-Control-Request-Method: POST
> Access-Control-Request-Headers: X-Requested-With
>
< HTTP/1.1 200 OK
< Cache-Control: private
< Vary: Accept
< Server: Microsoft-IIS/8.0
< X-Powered-By: ServiceStack/4.036 Win32NT/.NET
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
< Access-Control-Allow-Headers: Content-Type
< X-AspNet-Version: 4.0.30319
< X-SourceFiles: =?UTF-8?B?QzpccHJvamVjdHNcc2VydmljZXN0YWNrLXRvZG8tYmFja2VuZFxUb0RvQmFja2VuZFxUb0RvQmFja2VuZFxpdGVtcw==?=
< X-Powered-By: ASP.NET
< Date: Thu, 22 Jan 2015 23:51:29 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact
* Closing connection #0

这是本地IIS7.5中的结果:

curl -H "Origin: http://www.example.com" -H "Access-Control-Request-Method: P
OST" -H "Access-Control-Request-Headers: X-Requested-With" -X OPTIONS --verbose
 http://localhost/sstodo/items
* timeout on name lookup is not supported
* About to connect() to localhost port 80 (#0)
*   Trying 127.0.0.1...
* connected
* Connected to localhost (127.0.0.1) port 80 (#0)
> OPTIONS /sstodo/items HTTP/1.1
> User-Agent: curl/7.26.0
> Host: localhost
> Accept: */*
> Origin: http://www.example.com
> Access-Control-Request-Method: POST
> Access-Control-Request-Headers: X-Requested-With
>
< HTTP/1.1 200 OK
< Cache-Control: private
< Vary: Accept
< Server: Microsoft-IIS/7.5
< X-Powered-By: ServiceStack/4.036 Win32NT/.NET
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
< Access-Control-Allow-Headers: Content-Type
< X-AspNet-Version: 4.0.30319
< X-Powered-By: ASP.NET
< Date: Sat, 24 Jan 2015 02:44:55 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact
* Closing connection #0

当我 运行 针对 AzureWebSites(和 AppHarbor)进行测试时,它没有。

curl -X OPTIONS 
 -H "Origin: http://www.example.com" 
 -H "Access-Control-Request-Method: POST" 
 -H "Access-Control-Request-Headers: X-Requested-With" 
 --verbose http://sstodo.azurewebsites.net/items
* timeout on name lookup is not supported
* About to connect() to sstodo.azurewebsites.net port 80 (#0)
*   Trying 23.101.118.145...
* connected
* Connected to sstodo.azurewebsites.net (23.101.118.145) port 80 (#0)
> OPTIONS /items HTTP/1.1
> User-Agent: curl/7.26.0
> Host: sstodo.azurewebsites.net
> Accept: */*
> Origin: http://www.example.com
> Access-Control-Request-Method: POST
> Access-Control-Request-Headers: X-Requested-With
>
* Empty reply from server
* Connection #0 to host sstodo.azurewebsites.net left intact
curl: (52) Empty reply from server
* Closing connection #0

这是 AppHarbor:

curl -X OPTIONS 
 -H "Origin: http://www.example.com" 
 -H "Access-Control-Request-Method: POST" 
 -H "Access-Control-Request-Headers: X-Requested-With" 
 --verbose http://sstodo.apphb.com/items
* timeout on name lookup is not supported
* About to connect() to sstodo.apphb.com port 80 (#0)
*   Trying 50.17.211.206...
* connected
* Connected to sstodo.apphb.com (50.17.211.206) port 80 (#0)
> OPTIONS /items HTTP/1.1
> User-Agent: curl/7.26.0
> Host: sstodo.apphb.com
> Accept: */*
> Origin: http://www.example.com
> Access-Control-Request-Method: POST
> Access-Control-Request-Headers: X-Requested-With
>
* Empty reply from server
* Connection #0 to host sstodo.apphb.com left intact
curl: (52) Empty reply from server
* Closing connection #0

我有点迷茫。在我的心智模型中,我应该能够在我的本地环境中重现该问题。我看到的所有关于 Azure 和 AppHarbor 的文档都表明它们没有阻止 OPTIONS 调用,但事实并非如此。

当然,我不太关心站点在 cURL 中的工作方式。

嗯...不确定这是否有帮助,但我有一个 'works from my machine' 给你。屏幕截图如下...

如果您解决了自己的问题,我很想看看修复结果。

最后,成功的方法是切换到 HTTPS。

我不能说我明白为什么,但使用 HTTPS 总能解决问题。

我打赌你 运行 会遇到我遇到的同样问题; OS X 笔记本电脑上的 Cisco VPN 客户端 运行 中的 "Web Security" 模块拦截了您的 HTTP 请求,并默默地丢弃了作为 CORS 预检一部分的 OPTIONS 请求。这个 VPN 软件真是太棒了 "feature"。它甚至在您不使用 VPN 时执行此操作。

切换到 https 可以解决此问题,因为代理无法读取您的请求,因此无法删除 OPTIONS。

有关此问题的更多信息:http://www.bennadel.com/blog/2559-cisco-anyconnect-vpn-client-may-block-cors-ajax-options-requests.htm

您可以使用以下方法卸载网络安全模块: sudo /opt/cisco/anyconnect/bin/websecurity_uninstall.sh