我正在向运行express的节点服务器发送CORS ajax请求。在服务器日志和js控制台中,我可以看到预检OPTIONS请求成功。
然后,主要请求也在服务器上成功,并以200响应,我认为是正确的标题。但是,在Chrome中,网络标签将后一个请求报告为“已取消”,并且不接受或处理响应:
XMLHttpRequest无法加载http://myserver.com/upload。 Access-Control-Allow-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网络标签中的屏幕截图 - “已取消”的屏幕截图是200以上
答案 0 :(得分:5)
解决与CORS相关的问题
- 如果您尝试重现问题,并且没有看到请求/响应,您的浏览器可能已缓存了之前失败的预检请求尝试。清除浏览器的缓存也可能会清除预检缓存......
我在test-cors.org上测试了以下配置,但似乎可行。只需记住在进行故障排除时不时清除缓存。
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
});
}
}
祝你好运!
答案 1 :(得分:0)
事实证明,因为我同时使用nginx和express设置来响应选项请求的标头,所以它以某种方式将Access-Control-Allow-Origin标头值组合成“”,“”。我不知道它是作为一个数组还是什么来读。
仍然非常困惑,因为1)为什么请求让它通过nginx? 2)如果OPTIONS标题搞砸了,为什么浏览器会继续POST?
哦,这一课,一如既往 - 不要重复自己。