【问题标题】:Chrome/IE abort POST responseChrome/IE 中止 POST 响应
【发布时间】:2024-04-20 05:05:01
【问题描述】:

Chrome 和 Microsoft IE 正在中止 POST 响应,但它在 Firefox 中运行良好。当我通过 Fiddler 运行测试时,我注意到 Chrome/IE 中的 POST 标头不包含 Cache-Control: max-age=0Origin: ...,但在其他方面是相同的。

在 Chrome 中,当我按下提交按钮时,POST 会被发送到服务器并进行处理,然后客户端会中止响应。经过几次转发,客户端终于接受了响应;但是服务器已经处理了请求,因此会导致重复信息。这在 Firefox 上永远不会发生,它总是接受第一个响应。

似乎只有在请求很大时才会发生(即:包含更多字段供服务器处理)导致我认为这与服务器处理请求所需的时间有关(在Firefox 该请求显示为大约需要 9 秒)。

Firefox 中有什么东西会导致它等待这个响应的时间更长吗?或者反之亦然,IE/Chrome 中的某些东西可能会使其过早结束?

它可能不相关,但这是一个 Perl Mason 站点。提交表单的页面中的响应头:

HTTP/1.1 200 OK
Date: Tue, 07 Aug 2018 19:08:57 GMT
Server: Apache
Set-Cookie: ...; path=/
Set-Cookie: TUSKMasonCookie=...; path=/
Expires: Mon, 1 Jan 1990 05:00:00 GMT
Pragma: no-cache
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive

【问题讨论】:

  • 如果 firefox 假冒 9 秒,您可以尝试将超时值从 5 秒增加到 5 秒
  • 刚刚尝试过,但不幸的是仍然看到问题。

标签: javascript google-chrome http firefox browser


【解决方案1】:

原来是页面上的 Javascript 负责重新发布。一个setTimeout() 递归调用了它自己的函数,即使在表单数据已经发布到方法中之后,它也会继续被设置。

在 Chrome/IE/Edge 中,表单提交将被 POST,并且该函数将继续设置另一个超时调用自身。随后的调用将再次 POST 并中止等待原始的连接。

但 Firefox 不会重新发布,尽管它也会继续设置和调用该功能。

修复是添加一个标志来跟踪 POST 的提交时间和设置时间,以停止超时周期:

function countdown(secs, starttime) {
    var d = new Date();
    if (!starttime) {
        starttime = d.getTime() / 1000;
    }
    var nowtime = d.getTime() / 1000;
    var timeleft = (starttime + secs) - nowtime;
    timeleft = Math.max(0, timeleft);

    var isposted = false; // <-- Added as fix
    if (timeleft == 0) {
        isposted = true; // <-- Added as fix
        alert("Time is up. Click OK.");
        var frm = document.getElementById("frm");
        frm.submit();
    }

    if (!isposted) { // <-- Added as fix
        timeout = setTimeout(["countdown(", secs, ", ", starttime, ")"].join(""), 1000);
    }
}

【讨论】: