CORS pre-flight返回访问控制允许来源:*,浏览器仍然失败的请求

触发一个AJAX GEThttp://qualifiedlocalhost:8888/resource.json启动预计的CORS pre-flight,这看起来像是回来了:

飞行前OPTIONS请求

 Request URL:http://qualifiedlocalhost:8888/resource.json Request Method:OPTIONS Status Code:200 OK 

请求头

 Accept:*/* Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8 Access-Control-Request-Headers:accept, origin, x-requested-with Access-Control-Request-Method:GET Cache-Control:no-cache Connection:keep-alive Host:qualifiedlocalhost:8888 Origin:http://localhost:9000 Pragma:no-cache Referer:http://localhost:9000/ User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36 

响应头

 Access-Control-Allow-Headers:Content-Type, X-Requested-With Access-Control-Allow-Methods:GET,PUT,POST,DELETE Access-Control-Allow-Origin:* Connection:keep-alive Content-Length:2 Content-Type:text/plain Date:Thu, 01 Aug 2013 19:57:43 GMT Set-Cookie:connect.sid=s%3AEpPytDm3Dk3H9V4J9y6_y-Nq.Rs572s475TpGhCP%2FK%2B2maKV6zYD%2FUg425zPDKHwoQ6s; Path=/; HttpOnly X-Powered-By:Express 

看起来不错?

所以它应该工作,对吧?

但随后的请求仍然失败,错误XMLHttpRequest cannot load http://qualifiedlocalhost:8888/resource.json. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin. XMLHttpRequest cannot load http://qualifiedlocalhost:8888/resource.json. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin.

真正的要求

 Request URL:http://qualifiedlocalhost:8888/resource.json 

请求头

 Accept:application/json, text/plain, */* Cache-Control:no-cache Origin:http://localhost:9000 Pragma:no-cache Referer:http://localhost:9000/ User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36 X-Requested-With:XMLHttpRequest 

帮帮我!

也许它正盯着我。 但是,有什么想法? 以防万一它是相关的…我正在使用一个AngularJS $resource和一个CompoundJS服务器交谈。

改变你的Access-Control-Allow-Methods:'GET,POST'到'GET,POST,PUT,DELETE'

之前:

  app.use(function(req, res, next) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization'); next(); }); 

后:

 app.use(function(req, res, next) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT ,DELETE'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization'); next(); }); 

您的Web服务器/获取function还包括HTTP头:访问控制,允许来源? 我最终发现使用AngularJS 1.0.7和远程Java servlet获得了成功。 这是我的Java代码片段 – AngularJS客户端不需要进行任何更改:

Servlet的:

 @Override protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Send Response super.doOptions(request, response); response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With"); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* ... */ response.setHeader("Access-Control-Allow-Origin", "*"); } 

一个更优雅的select是一个servletfilter。

我最近有同样的问题 。 问题在于,必须在预检响应和实际响应中发送Access-Control-Allow-Origin头(以及,如果使用Access-Control-Allow-Credentials头)。

你的例子只有在预检反应中才有。

我们一直在注意到服务器发送正确的CORS头的相同的问题,但浏览器因为认为CORS的要求没有得到满足而失败。 更有趣的是,在我们的例子中,它只发生在同一浏览器会话中的一些AJAX调用,但不是全部。

工作理论…

清除浏览器caching解决了在我们的情况下的问题 – 我目前的工作理论是,这是由交叉原点服务器设置cookie。 我注意到在你的情况下,有一个cookie被设置为响应飞行前OPTIONS请求的一部分。 你有没有尝试让服务器不设置任何来自不同来源的请求的cookie?

但是,我们注意到在某些情况下,重置浏览器后,问题又重新出现了。 另外,在私有模式下运行浏览器会导致问题消失,指出浏览器caching中存在的问题。

作为参考,这里是我的情况(我几乎把这个作为一个新的问题在SO,但是把它放在这里):

我们遇到了一个错误,通过jQuery.ajax发出的一些 CORS GET请求失败。 在一个给定的浏览器会话中,我们看到预购的OPTIONS请求经过,然后是实际的请求。 在同一个会话中,有些请求会通过,而有些请求会失败。

浏览器networking控制台中的请求和响应顺序如下所示:

首先select飞行前请求

 OPTIONS /api/v1/users/337/statuses HTTP/1.1 Host: api.obfuscatedserver.com Connection: keep-alive Access-Control-Request-Method: GET Origin: http://10.10.8.84:3003 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36 Access-Control-Request-Headers: accept, origin, x-csrf-token, auth Accept: */* Referer: http://10.10.8.84:3003/ Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 

这得到了一个回应,

 HTTP/1.1 200 OK Date: Tue, 06 Aug 2013 19:18:22 GMT Server: Apache/2.2.22 (Ubuntu) Access-Control-Allow-Origin: http://10.10.8.84:3003 Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT Access-Control-Max-Age: 1728000 Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: accept, origin, x-csrf-token, auth X-UA-Compatible: IE=Edge,chrome=1 Cache-Control: no-cache X-Request-Id: 4429c4ea9ce12b6dcf364ac7f159c13c X-Runtime: 0.001344 X-Rack-Cache: invalidate, pass X-Powered-By: Phusion Passenger 4.0.2 Status: 200 OK Vary: Accept-Encoding Content-Encoding: gzip 

然后,实际的GET请求,

 GET https://api.obfuscatedserver.com/api/v1/users/337 HTTP/1.1 Accept: application/json, text/javascript, */*; q=0.01 Referer: http://10.10.8.84:3003/ Origin: http://10.10.8.84:3003 X-CSRF-Token: xxxxxxx User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36 auth: xxxxxxxxx 

在浏览器控制台中出现错误,

 XMLHttpRequest cannot load https://api.obfuscatedserver.com/api/v1/users/337. Origin http://10.10.8.84:3003 is not allowed by Access-Control-Allow-Origin. 

其他debugging

我可以通过curl重放相同的序列,并且我看到来自服务器的有效响应。 即他们有期望的CORS头应该让请求通过。

在隐私/隐身浏览器窗口中运行相同的scheme不会重现该问题。 这导致我尝试清除caching,这也使问题也消失了。 但过了一段时间,它又回来了。

这个问题在iPhone safari上以及在OSX桌面上的Chrome上重现。

我真的需要帮助

我怀疑在这里涉及的跨域域中有一些Cookie设置,并可能暴露浏览器中的错误。 有没有工具或断点,我可以在浏览器中设置(本机堆栈?)来尝试和进一步debugging呢? 评估CORS策略的代码中的断点是理想的。

看起来你对“选项”的回应是正常的。 这个问题似乎是在'得到'的回应。

你会想让你的'get'响应返回与'options'响应相同的CORS头。

特别是,“获得”的回应应该包括

 Access-Control-Allow-Headers:Content-Type, X-Requested-With Access-Control-Allow-Methods:GET,PUT,POST,DELETE Access-Control-Allow-Origin:* 

使用Cors模块来避免这个问题

 var cors = require('cors') var app = express() app.use(cors())