【发布时间】:2021-05-18 09:43:52
【问题描述】:
我最初在 GitHub 上的 Actix discussion boards 上发布了这个问题,但我认为它可能会在 SO 中获得更多曝光,所以就这样吧。
所以,我有这样的设置:
// --snip--
.wrap(DefaultHeaders::new().header("cache-control", "public, max-age=5, must-revalidate"))
.service(
actix_files::Files::new("/", &settings.server.public_dir)
.index_file(&settings.server.index_file)
)
// --snip--
如果我在没有 SSL 的情况下运行我的服务器,它默认为 HTTP/1.1,因此当我向静态文件(例如 app.js)发出请求(任何浏览器)时,一切都会按我的预期运行。服务器返回 200 状态,其中包含正确的文件和正确的缓存标头以及 ETag 和 Last-Modified 标头。 Etags 和 last modified 默认是开启的。
如果我在 5 秒内发出后续请求,也不足为奇 - 浏览器不会尝试新请求,因为它们已将文件缓存 5 秒。
当我在 5 秒内发出另一个请求时,浏览器会正确地向服务器发送条件请求,包括带有 app.js 的预期 etag 值的 if-none-match 标头,并且服务器将正确返回 304 Not Modified 响应无需在响应正文中实际发送文件。
RESPONSE: Ok(
ServiceResponse HTTP/1.1 304 Not Modified
headers:
"last-modified": "Mon, 08 Feb 2021 14:56:48 GMT"
"accept-ranges": "bytes"
"cache-control": "public, max-age=5, must-revalidate"
"content-encoding": "gzip"
"content-type": "image/jpeg"
"etag": "\"c55582f:11923:60215130:4678e1d\""
"content-disposition": "inline; filename=\"test.jpeg\""
body: Stream
)
这里也没有什么意外,因为这种行为正是我所期望的。问题是当我启用 SSL 并且我的服务器开始通过 HTTP/2 返回流媒体主体时。
Chrome 和 Firefox 浏览器的行为与以前完全相同,如果 5 秒后发出后续请求并且收到 304 响应,它们会再次请求资源,它们只是从缓存中加载我的 app.js。
另一方面,Safari(在 macOS 和 iOS 上)完全不知道如何处理 304 响应。它确实正确发送了 if-none-match 和 since-last-modified 标头,但是当 actix 回复 304 时,它无法加载我的静态文件。
“网络”选项卡也无济于事:
上面写着“无响应标头”的地方显然是废话,因为我可以在 Actix 中调试标头并查看它们实际上是正确的:
RESPONSE: Ok(
ServiceResponse HTTP/1.1 304 Not Modified
headers:
"last-modified": "Sun, 14 Feb 2021 10:54:28 GMT"
"accept-ranges": "bytes"
"content-encoding": "br"
"content-type": "application/javascript"
"etag": "\"a352043:2db3:60290164:2f00192\""
"content-disposition": "attachment; filename=\"VideoPlayer.js\""
body: Stream
)
我注意到,当浏览器没有缓存文件时,在第一次请求文件时,响应是 HTTP/2,但对条件请求的响应是 HTTP/1.1,如您在以上摘录。
在这个问题上停留了一段时间,因此非常感谢任何帮助或指导。
谢谢!
【问题讨论】:
-
Safari 似乎存在 304 问题:stackoverflow.com/questions/32281359/…
标签: rust safari http2 actix-web