CORS:预检通过,主要请求完成w / 200,但浏览器仍然有Origin错误

我正在向运行express的节点服务器发送CORS ajax请求。 在服务器日志和js控制台中,我都可以看到预检OPTIONS请求成功。

然后,主要的请求也成功的服务器和响应200和我认为是正确的标题。 但是,在Chrome中,networking标签会将后一个请求报告为“已取消”,并且不会接受或处理该响应:

XMLHttpRequest无法加载http://myserver.com/upload 。 Access-Control-Allow-Origin不允许Origin http://mysite.com 。

以下是服务器日志,其中包含为请求和响应打印的标题:

76.79.201.210 - - [27/Jun/2013:23:23:17 +0000] "OPTIONS /upload HTTP/1.1" 204 0 "http://mysite.com/add" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36" START { host: 'localhost:5001', connection: 'close', 'content-length': '109587', origin: 'http://mysite.com', 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36', 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryBZA4TATeeVWMHArH', accept: '*/*', referer: 'http://mysite.com/add', 'accept-encoding': 'gzip,deflate,sdch', 'accept-language': 'en-US,en;q=0.8' } { 'x-powered-by': 'Express', 'access-control-allow-origin': '*', 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS', 'access-control-allow-headers': 'X-Requested-With' } XX.XX.XXX.210 - - [27/Jun/2013:23:23:19 +0000] "POST /upload HTTP/1.1" 200 118 "http://mysite.com/add" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36" - - - [Thu, 27 Jun 2013 23:23:19 GMT] "POST /upload HTTP/1.0" 200 - "http://mysite.com/add" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36" 

更新:从Chrome的networking标签截图 – “取消”是一个200以上的

Screen Shot 2013-06-27 at 5.25.25 PM.png

排除与CORS相关的问题

  • 如果您试图重现问题,并且没有看到请求/响应, 则浏览器可能会caching较早的失败的预检请求尝试 。 清除浏览器的caching也可能会清除预检caching…

https://developers.google.com/storage/docs/cross-origin

我在test-cors.org上testing了以下configuration,它似乎工作。 只要记住要在排除故障时不时清除caching。

 var allowedHost = { // this is the origin that test-cors.org uses 'http://client.cors-api.appspot.com': true }; var allowCrossDomain = function(req, res, next) { if (!req.headers.origin || allowedHost[req.headers.origin]) { res.header('Access-Control-Allow-Credentials', true); res.header('Access-Control-Allow-Origin', req.headers.origin) res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); res.header('Access-Control-Allow-Headers', 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version'); if (req.method == 'OPTIONS') res.send(200); else next(); } else { res.send(403, { auth: false }); } } 

祝你好运!

所以事实certificate,因为我已经把nginx和express设置为响应选项请求的头部,所以它以某种方式将Access-Control-Allow-Origin头部值合并到“ ”,“ ”中。 我不知道它是作为一个数组还是什么读的。

仍然非常困惑,因为1)为什么请求通过nginx? 和2)为什么浏览器进行POST如果OPTIONS标题搞砸了?

哦,一如既往的教训 – 不要重复自己。