Chrome 为什么会发出两次请求的原因

7
以下是我在 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"
问题在于访问的链接是不可重复使用的资源(只能访问一次),因此客户端会遇到错误。
这些链接是用 JavaScript 代码调用的文件下载,其中涉及 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

你在Chrome的网络选项卡中看到两个请求被发出了吗? - Chris
@Chris,就像我说的一样-我无法在我的浏览器上重现这个问题。这是发生在客户端的Chrome上。问题是什么可能导致Windows Chrome安装中的这种异常情况。 - Slavic
你知道GET请求应该是幂等的吧? - Caltor
1
@Caltor,不是所有的GET请求都是幂等的,但如果它们是幂等的话会更好。 - Slavic
如果您想遵守RFC7231 https://tools.ietf.org/html/rfc7231#section-8.1.3,那么就需要这样做。如果一个“蜘蛛”访问您的网站并决定访问每个GET,则可能会遇到麻烦。不过请注意,我说的是“应该”而不是“必须”。 - Caltor
显示剩余8条评论
1个回答

0

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

如果你有一个不安全/非幂等的GET请求,那么如果客户端进行多个请求(它应该是自由进行的)或者类似索引“蜘蛛”或预取缓存访问你的站点并决定访问它能找到的每个GET端点,你就会面临问题。详见https://www.rfc-editor.org/rfc/rfc7231#section-8.1.3了解哪些HTTP方法是安全和幂等的细节。


你说得对,这不是被问问题的答案。我并不质疑 web 的架构,我只是在说这是那种情况,当模具无法完全契合时。这些 GET 请求所请求的资源是短暂的。此外,爬虫也不可行,因为那些 url 是“秘密”的。 - Slavic
@Slavic 确实,但我认为您正在问错问题。这让我想到了 XY 问题 (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) 您正在问“为什么 Chrome 会发出两次请求?”(Y),而我认为您应该问“如何阻止资源过早删除” (X)。如果您真的得到了答案,您的问题可能最终会得到网络而不是编程方面的答案,并且可能更适合于不同的 stackexchange 网站,例如 serverfault.com。 - Caltor
我不介意得到一个网络答案,因为我已经有了你认为我应该问的问题的答案。你是对的,这需要更多基于实证而非协议和理论的答案。 - Slavic
@Slavic Cool,我建议使用Wireshark来捕获网络流量,然后在serverfault上发布您的问题和/或在您的问题中发布客户端和服务器代码,以便这里的某个人可以尝试并查看您的代码是否存在问题。 - Caltor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接