http - If-None-Match 标头忽略 Content-Type 和 Vary
问题描述
我有一个提供 HTML 和多种 RDF 格式的 Web 应用程序(在下面的示例中,它是 RDF/XML)。页面加载为 HTML(自然),然后请求其自己的 URL 作为 RDF/XML。
问题:看起来 Firefox 74.0(64 位)(在 Windows 上)混合了ETag
这两个请求的值,忽略了不同Content-Type
的 s 以及Vary: Accept
存在。
当我重新加载页面时,我可以看到它使用ETag: "95e11fbc9e816b56"
HTML 请求中的第二个(RDF/XML)响应,反之亦然:
Request URL: https://localhost:4443/6a6283d2-2a40-4882-b89d-8073a7c30e17/
Host: localhost:4443
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://localhost:4443/6a6283d2-2a40-4882-b89d-8073a7c30e17/
Connection: keep-alive
Cookie: _ga=GA1.1.828629977.1584086266; LinkedDataHub.first-time-message=true
Upgrade-Insecure-Requests: 1
If-None-Match: "95e11fbc9e816b56"
Cache-Control: max-age=0
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Strict-Transport-Security: max-age=31536000;includeSubDomains
ETag: "95e11fbc139f56de"
Cache-Control: max-age=3600, public
Last-Modified: Wed, 12 Feb 2020 23:05:15 GMT
Vary: Accept-Charset,Accept,Accept-Encoding
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Content-Encoding: gzip
Date: Sun, 22 Mar 2020 10:13:43 GMT
Request URL: https://localhost:4443/6a6283d2-2a40-4882-b89d-8073a7c30e17/
Host: localhost:4443
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: application/rdf+xml
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://localhost:4443/d376ee88-ff7d-48ee-81c4-1220c9f482f0/
Connection: keep-alive
Cookie: _ga=GA1.1.828629977.1584086266; LinkedDataHub.first-time-message=true
If-None-Match: "95e11fbc139f56de"
Cache-Control: max-age=0
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Strict-Transport-Security: max-age=31536000;includeSubDomains
ETag: "95e11fbc9e816b56"
Last-Modified: Wed, 12 Feb 2020 23:05:15 GMT
Vary: Accept-Charset,Accept
Content-Type: application/rdf+xml;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 22 Mar 2020 10:13:55 GMT
在 Chrome 上,我根本无法让它发送If-None-Match
标头,但这可能是由于 self-signed certificate。
请注意,这些ETag
值相似,但不同:"95e11fbc139f56de"
与"95e11fbc9e816b56"
.
这对我来说没有任何意义。有什么解释吗?谢谢。
相关规范是Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests。
解决方案
本质上,问题在于您所依赖的行为不是 HTTP 标准规定的,也不是浏览器实现的。
为了使您的方案正常工作,浏览器必须在其缓存中存储单个资源的多个表示。不幸的是,正如这些文章中所讨论的那样 ,他们没有这样做。
浏览器通常不会实现为每个 URL 存储多个变体的功能。这样做的理由是我们通常使用 Vary 的东西(主要是 Accept-Encoding 和 Accept-Language)在单个用户的上下文中不会经常更改。
所以问题不在于ETags
,而在于浏览器每次获得不同的表示时都会覆盖其缓存中的单个表示。
如果浏览器确实存储了多个表示,则该方案应该可以正常工作。在这种情况下,请注意在多个ETags
. 客户端将发送一个包含它所知道If-None-Match
的所有信息的标头ETags
,并且由服务器决定哪个(如果有)与请求的表示匹配。
根据上面的文章,边缘服务器(相对于浏览器)确实在缓存中为每个资源保留了多个表示,因此您的方案仍然有可能产生性能提升。
推荐阅读
- boost-test - 观察测试失败消息
- reporting-services - 如何获得累积总和 SSRS 报告?
- azure - 如何在 Azure API 管理 Python SDK 中使用筛选器
- css - 我如何停止 prepos 来创建除 main.scss 之外的某些已编译的 scss
- android - React Native - 用于将我的应用程序提交到 Google Play 的未优化 APK
- ios - xib 显示空白框,即使我们在 Xcode 中有很多视图和其他设计
- vim - 摆脱 vim 的“netrw”插件
- c# - 如何检查gridviewrow中是否选中了复选框
- wpf - 用于填充 ListBox 的 LINQ to SQL 查询返回错误结果
- python - 为什么我得到 DatasetV1Adapter 返回类型而不是 tf.data.Dataset.from_tensor_slices(X) 的 TensorSliceDataset