Chrome/Firefox 在后台发送两个 POST,间隔恰好 5 秒,仅调用一次来获取 Nodejs 8.0.0 服务器

2024-05-19

注意:这不是飞行前选项,也不是网站图标或其他类似内容。实际上是 2 个帖子。下面有一个屏幕截图可以更清楚地显示这一点。

我的规格/版本:

  • macOS 塞拉利昂版本 10.12.3
  • Chrome 版本 61.0.3128.0(官方版本)开发版(64 位)
  • 节点 v8.0.0

我有一个服务器,它使用 setTimeout 在响应之前等待 10 秒。我有一个向服务器发出单个 POST 的前端。使用wireshark,我可以看到浏览器实际上发出了 2 个 POST,第二个是在 t+5 秒发出的。服务器会看到这两个 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);
});

Here is a screenshot of the server, the frontend console and the wireshark traffic: enter image description here

And here is the network tab. You can see the request is 'stalled' for 5 seconds. enter image description here

我所做的测试的一些附加说明:

这种情况在 Chrome 和 Firefox 中会发生,但在 Safari 中不会。 (我使用的是 mac,chrome 版本 60.0.3112.20(官方版本)开发版(64 位))这可能只发生在 CORS 中,但无法通过最小的测试用例进行确认。我用 jQuery 尝试过ajax看看它是否可能与 fetch 有关,但它仍然发生了。 (我将检查 jQuery 源代码,看看它是否仍在幕后使用 xhr,因为我实际上不确定它是否没有移至 fetch。)


事实证明这是 Node 8.0.0 的一个错误,并已被 8.1.1 修复。

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Chrome/Firefox 在后台发送两个 POST,间隔恰好 5 秒,仅调用一次来获取 Nodejs 8.0.0 服务器 的相关文章

随机推荐