【问题标题】:Long XHR POST stalls on Android devices using Chrome (HTTP status 408)使用 Chrome 的 Android 设备上的长 XHR POST 停止(HTTP 状态 408)
【发布时间】:2020-10-15 08:11:59
【问题描述】:

Solved. 是由第 3 方应用引起的...

我在尝试使用 PHP 实现文件上传时遇到了一个奇怪的问题。如果我使用 XHR 发布一个大负载,它会经常但不总是在我运行 Chrome (72.0.3626.96) 的 Android (7.0) 设备上停止。 Android 设备会无缘无故地停止发送有效负载。这根本无法在 PC 上重现,而且我没有任何其他 Android 设备可供测试。

更新:我使用这个来自 github 的经过良好测试的 XHR 上传代码得到了同样的奇怪行为:https://gist.github.com/ebidel/2410898

服务器在 Raspbian Buster 上运行 nginx/1.14.2 和 PHP 7.3.14-1~deb10u1。 这是整个 PHP 页面:

<!DOCTYPE html>
<html>
<div id="prog" style="background:#555;height:30px;"></div>
<script>
function Xhr(addr, arg, fdone, fprog){
    var xhr;
    xhr = new XMLHttpRequest();
    xhr.open("POST", addr, true);
    xhr.onreadystatechange = function() {   //call done() when done
        if (fdone && this.readyState == 4) fdone(this.status, this.responseText);
    }
    if (fprog && xhr.upload) {              //call prog() on progress
        xhr.upload.onprogress = fprog; xhr.upload.onload = fprog;
    }
    xhr.send(arg);
}
function prog(e){
    var p = 0;
    if (e.type == "load") p = 1;
    else if (e.lengthComputable) p = e.loaded / e.total;
    progbar.style.width = (p*100) + "%";
}
function done(stat){
    alert(stat);
}

var progbar=document.getElementById("prog");

//sends 5MB of data to itself
Xhr("test1.php", 'x'.repeat(5*1024*1024), done, prog);

</script>
</html>

当被访问时,它只是用 XHR 将 5MB 的数据发送到它自己的地址。出于测试目的,PHP 只是忽略了这里的传入数据。进度条出现在顶部。

预期行为: 在 PC 上,进度条平滑地上升到 100%,并且 done() 函数接收 HTTP 状态 200

观察到的行为: 在我使用 Chrome 的 Android 设备上,进度条动画非常不稳定,通常会立即超过 50%,然后在剩下的时间里非常缓慢地上升,然后完全停止。 30 秒后,当服务器因不活动而断开连接时,done() 函数收到状态 0,而 nginx 将状态 408 Request 记录到访问日志中。

有趣的是,手机上的进度条上升了 50% 以上,而服务器收到的有效负载不到 10%。此外,打开页面时它立即上升的速度越快,POST失败的可能性就越大。 POST确实在大约 5% 的时间里成功,总是在打开页面时进度条以低于 50% 的速度开始时!

欢迎任何想法,我真的很茫然......

以下是服务器接收 POST 时的数据包转储:

(initial handshake)
19:08:06.321379 IP cli.54556 > server.https: Flags [S], seq 2067394220, win 65535, options [mss 1460,sackOK,TS val 10030824 ecr 0,nop,wscale 8], length 0
19:08:06.321653 IP server.https > cli.54556: Flags [S.], seq 2059855015, ack 2067394221, win 65160, options [mss 1460,sackOK,TS val 2173911984 ecr 10030824,nop,wscale 7], length 0
(client GETs test1.php)
19:08:06.325516 IP cli.54556 > server.https: Flags [.], ack 1, win 343, options [nop,nop,TS val 10030824 ecr 2173911984], length 0
19:08:06.328377 IP cli.54556 > server.https: Flags [P.], seq 1:518, ack 1, win 343, options [nop,nop,TS val 10030824 ecr 2173911984], length 517
19:08:06.328542 IP server.https > cli.54556: Flags [.], ack 518, win 506, options [nop,nop,TS val 2173911991 ecr 10030824], length 0
19:08:06.330067 IP server.https > cli.54556: Flags [P.], seq 1:149, ack 518, win 506, options [nop,nop,TS val 2173911992 ecr 10030824], length 148
(client POSTs test1.php)
19:08:06.336971 IP cli.54556 > server.https: Flags [.], ack 149, win 347, options [nop,nop,TS val 10030825 ecr 2173911992], length 0
19:08:06.341623 IP cli.54556 > server.https: Flags [P.], seq 518:561, ack 149, win 347, options [nop,nop,TS val 10030826 ecr 2173911992], length 43
(payload send start)
19:08:06.342874 IP cli.54556 > server.https: Flags [.], seq 561:2009, ack 149, win 347, options [nop,nop,TS val 10030826 ecr 2173911992], length 1448
19:08:06.343051 IP cli.54556 > server.https: Flags [.], seq 2009:3457, ack 149, win 347, options [nop,nop,TS val 10030826 ecr 2173911992], length 1448
19:08:06.343238 IP cli.54556 > server.https: Flags [.], seq 3457:4905, ack 149, win 347, options [nop,nop,TS val 10030826 ecr 2173911992], length 1448
19:08:06.343462 IP cli.54556 > server.https: Flags [.], seq 4905:6353, ack 149, win 347, options [nop,nop,TS val 10030826 ecr 2173911992], length 1448
19:08:06.343612 IP server.https > cli.54556: Flags [.], ack 4905, win 501, options [nop,nop,TS val 2173912006 ecr 10030826], length 0
19:08:06.343721 IP cli.54556 > server.https: Flags [.], seq 6353:7801, ack 149, win 347, options [nop,nop,TS val 10030826 ecr 2173911992], length 1448
19:08:06.343871 IP cli.54556 > server.https: Flags [.], seq 7801:9249, ack 149, win 347, options [nop,nop,TS val 10030826 ecr 2173911992], length 1448
19:08:06.344006 IP cli.54556 > server.https: Flags [.], seq 9249:10697, ack 149, win 347, options [nop,nop,TS val 10030826 ecr 2173911992], length 1448
19:08:06.344245 IP server.https > cli.54556: Flags [.], ack 10697, win 501, options [nop,nop,TS val 2173912006 ecr 10030826], length 0
...
(~200 lines similar suppressed)
19:08:06.436894 IP server.https > cli.54556: Flags [.], ack 349529, win 3810, options [nop,nop,TS val 2173912099 ecr 10030834], length 0
19:08:06.436962 IP cli.54556 > server.https: Flags [.], seq 349529:350977, ack 149, win 347, options [nop,nop,TS val 10030834 ecr 2173912076], length 1448
19:08:06.437268 IP cli.54556 > server.https: Flags [.], seq 350977:352425, ack 149, win 347, options [nop,nop,TS val 10030834 ecr 2173912076], length 1448
(client stopped sending to server)
(server sends a reset packet 30sec later)
19:08:38.437081 IP server.https > cli.54556: Flags [R.], seq 149, ack 361094, win 3991, options [nop,nop,TS val 2173944099 ecr 10030834], length 0
(XHR fails with status 0, server logs error 408 to access log)

【问题讨论】:

    标签: php android google-chrome xmlhttprequest


    【解决方案1】:

    事实证明,旧版本的 NetGuard (2.97) 会导致 任何 大型上传出现这种行为,而不仅仅是在 Chrome 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-13
      • 2011-12-23
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      相关资源
      最近更新 更多