姜饼浏览器跨域响应串联错误

我们发现Gingerbread默认浏览器处理跨域请求的方式与大多数其他浏览器不同。 服务器代码适当地响应OPTIONS调用,所有正确的头文件访问控制头文件和一个200状态代码,并用200状态代码和适当的主体响应POST调用。 服务器是用Node编写的,使用Express,对于这个testing来说是非常小的:

 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); 

当姜饼浏览器对/路由发出CORS请求时,它收到了一个"OK{some:'json object'}"responseText 。 由于我们使用jQuery,并且由于Content-Type响应头是application/json ,所以jQuery由于不可parsing的json响应正文而失败了请求。 我们testing过的每个浏览器都使用"{some:'json object'}"进行响应,并按预期进行parsing。

那么“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,所以我们还是遇到了一个错误。

这里发生了什么?

事实certificate,姜饼 – 至less我们使用的版本 – 自动连接了OPTIONS请求和POST请求的响应。 此外,Express没有特定的主体和状态代码200 ,自动发送"OK"主体作为响应。

上面的例子使这个问题变得非常明显,但是我们并没有把它缩小到那个程度。 因此,我们追求已知工作版本和失败版本之间的标题之间的微小差别。