Chrome浏览器/火狐浏览器发送两个邮件正好5秒钟,只有一个调用来获取Nodejs 8.0.0服务器

注:这不是预检选项,它不是favicon或任何其他类似的。 这实际上是2 POSTS。 下面有一个截图,更清晰地显示出来。

我的规格/版本:

  • macOS Sierra版本10.12.3
  • Chrome版本61.0.3128.0(官方版本)dev(64位)
  • 节点v8.0.0

我有一个服务器,使用setTimeout等待10秒后才响应。 我有一个前端,使单个POST到服务器。 使用wireshark,我可以看到浏览器实际上做了2个POST,第二个在t + 5s。 服务器看到这两个POST并对两者都响应。 前端只能得到第二个POST的结果。

在下面的示例中,您将看到,获取实际需要15秒才能完成,而不是您希望从服务器中超时的10秒。

该呼叫是CORS,只有当服务器花费超过5秒的时间来响应时才会发生。

这里发生了什么,我该如何阻止它呢?

这是一个最小的复制:

server.js(与节点一起运行)

var http = require("http"); // A counter for the requests var counter = 0; var server = http.createServer(function(request, response) { // Closure to prevent the request number from changing with the counter. (function(requestNumber) { console.log('Incoming:', request.method, "assigning number", requestNumber); // CORS headers response.writeHead(200, { "Content-Type": "application/json", "Access-Control-Allow-Methods": "GET,HEAD,PUT,POST,DELETE", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "authorization,content-type,expect", }); // Respond to options immediately. if (request.method === "OPTIONS") { response.end() } else { // Otherwise simulate a long running process (db write whatever) setTimeout(function() { console.log('Timeout done, responding to request number', requestNumber); response.write(JSON.stringify({ number: requestNumber })); response.end(); }, 10000); } }(counter++)); }); server.listen(8080); console.log("Server is listening"); 

在前端获取呼叫:

 var start = new Date(); console.log('making call. Wait ~15 seconds for the result to come back'); fetch('http://localhost:8080', { headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, method: 'post', mode: 'cors', body: JSON.stringify({ some: 'content' }), }).then(result => result.json()).then(json => { console.log('result', json); console.log('call took:', (new Date() - start), 'seconds'); }).catch(err => { console.log('err', err); }); 

以下是服务器,前端控制台和wiresharkstream量的截图: 在这里输入图像描述

这里是networking标签。 您可以看到请求被“停止”了5秒钟。 在这里输入图像描述

一些额外的笔记,从我做的testing:

这发生在铬和Firefox,但不Safari浏览器。 (我在一个mac,铬版本60.0.3112.20(官方build设)dev(64位))这可能只发生在CORS,但还没有能够确认一个最小的testing用例。 我试着用jQuery的ajax来看看它是否可能是相关的,但它仍然发生。 (我将检查jQuery源代码,看看它是否仍在使用xhr,因为我不确定它是否没有移动到获取。)

所以事实certificate,这是一个节点8.0.0的bug,并已被8.1.1修复。

我没有确定确切的错误,但可能是其中之一:

https://github.com/nodejs/node/pull/13549

https://github.com/nodejs/node/commit/2cb6f2b281