Chrome 会发出两次请求的原因

Sla*_*vic 6 javascript google-chrome http

我的 nginx 服务器日志中有以下内容(为了示例而更改了 IP 和一些路径):

101.101.101.101 - - [15/Apr/2020:14:46:03 +0000] "GET /item/download-file/ready/5e971e290107e HTTP/2.0" 200 142940 " https://example.com/referer " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"

101.101.101.101 - - [15/Apr/2020:14:46:04 +0000] "GET /item/download-file/ready/5e971e290107e HTTP/1.1" 200 5 " https://example.com/referer " " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"

问题是访问的链接是针对非幂等资源的(只能访问一次),因此客户端会遇到错误。

这些链接用于文件下载,可通过涉及window.location.href = "...". 响应服务器标头包括Content-Disposition: attachment.

在什么情况下,Chrome 会先发送两个涉及 HTTP/2.0 的请求,稍后再发送 HTTP/1.1?也许有可能导致这种情况的扩展?

请注意,我无法在我拥有的任何浏览器中重现它。

更新 2:

我已经确定它不仅仅发生在 Chrome 中。Edge 44 也出现在日志中。此外,针对此问题的其他实例的第二个请求没有切换到 HTTP/1.1。相反,它们是 HTTP/2.0。

更新:

我被要求提供典型请求的响应头:

cache-control: no-store, no-cache, must-revalidate
content-disposition: attachment; filename=sources.zip
content-length: 8597357
content-transfer-encoding: Binary
content-type: application/octet-stream
date: Wed, 15 Apr 2020 17:23:44 GMT
expires: Thu, 19 Nov 1981 08:52:00 GMT
pragma: no-cache
server: nginx/1.16.1
status: 200
Run Code Online (Sandbox Code Playgroud)

Cal*_*tor 0

我不知道为什么你会收到多个请求(也许这只是 HTTP 2/1.1 协商),但真正的答案是你应该使 GET 请求安全且幂等,并要求客户端发送单独的 DELETE 请求。我知道这可能不是你想要的答案。

如果您有一个不安全/非幂等的 GET 请求,那么如果客户端发出多个请求(这应该是免费的),或者像索引“蜘蛛”或预取缓存之类的东西访问您的网站,那么您就会遇到问题决定访问它能找到的每个 GET 端点。有关哪些 HTTP 方法应该和不应该安全和幂等的详细信息,请参阅https://www.rfc-editor.org/rfc/rfc7231#section-8.1.3 。