【发布时间】:2013-07-29 23:10:21
【问题描述】:
我们发现 Gingerbread 默认浏览器处理跨域请求的方式与大多数其他浏览器不同。服务器代码适当地响应OPTIONS 调用,使用所有正确的标头访问控制标头和200 状态代码,并使用200 状态代码和适当的正文响应POST 调用。服务器是用 Node 编写的,使用 Express,并且出于本次测试的目的,它非常小:
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
// middleware
app.use(express.logger('dev'));
app.use(function(req, res, next) {
var origin = req.get('origin');
if (origin) {
res.header({
'Access-Control-Allow-Origin': origin,
'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Credentials': true
});
}
if (req.method === "OPTIONS")
return res.send(200);
if (req.method !== "GET" && req.method !== "POST")
return res.send(405);
next();
});
app.use(express.json());
app.use(app.router);
app.post('/the/route', function(req, res) {
res.json(200, {some: 'json object'});
});
server.listen(process.env.PORT || 3000);
当 Gingerbread 浏览器向 /the/route 发出 CORS 请求时,它收到了 responseText 的 "OK{some:'json object'}"。由于我们使用的是 jQuery,并且由于 Content-Type 响应标头是 application/json,因此 jQuery 由于无法解析的 json 响应主体而导致请求失败。我们测试过的所有其他浏览器都以"{some:'json object'}" 响应,并按预期进行解析。
那么“OK”从何而来?
我们进一步简化了服务器,完全忽略了app.router。也许这就是问题所在。
...
// middleware
app.use(express.logger('dev'));
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Credentials', true);
res.json(200, {some: 'json object'});
});
这一次,令我们惊讶的是,服务器在 Gingerbread 浏览器上响应 "{some:'json object'}{some:'json object'}",在所有其他浏览器上响应 "{some:'json object}"。当然,前者仍然不是有效的 json,所以我们还是遇到了错误。
这是怎么回事?
【问题讨论】:
标签: jquery json node.js xmlhttprequest cors