CORS pre-flight返回访问控制允许来源:*,浏览器仍然失败的请求
触发一个AJAX GET
到http://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())
- 护照js从跨域login?
- Node.js服务器应用程序使用cors,express和google api在azure部署后不工作
- Express Passport.js不保留会话中的用户对象
- 使用CORS XHR时,浏览器不发送cookies
- CORS的“Access-Control-Allow-Origin”值如何暴露给浏览器?
- AS3能够识别头部的CORS权限吗?
- 在ExpressJS中接受CORS请求的自定义HttpHeaders
- Angular / Node / Express / Passport跨域问题 – 启用CORS Passport Facebook身份validation
- OAuth中的CORS:对预检请求的响应不会通过访问控制检查