我们发现 Gingerbread 默认浏览器处理跨域请求的方式与大多数其他浏览器不同。服务器代码适当地响应OPTIONS
调用,所有正确的标题访问控制标题和状态代码,并用状态代码和适当的主体200
响应调用。服务器是用 Node 编写的,使用 Express,并且出于本测试的目的,它非常小:POST
200
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'});
});
这一次,令我们惊讶的是,服务器"{some:'json object'}{some:'json object'}"
在 Gingerbread 浏览器和"{some:'json object}"
其他所有浏览器上都做出了响应。当然,前者仍然不是有效的 json,所以我们仍然遇到了错误。
这里发生了什么?