http - Cache-Control 请求标头是否应该影响服务器端缓存?
问题描述
A 已经看到很多关于RFC7234和 Cache-Control 标头的代理的讨论,但我不太清楚请求标头是否应该影响服务器端缓存。
下图显示了我关注的标头所在的位置(向下箭头是请求标头,向上箭头是响应标头):
┌────────┐
│ Client │
└────────┘
↓ ↑
┌────────┐
│ Cache │
└────────┘
↓ ↑
┌────────┐
│ Cache │
└────────┘
↓ ↑
┌────────┐
│ Server │
└────────┘
??? → ↓ ↑
┌─────────────┐
│ Server-side │
│ Cache │
└─────────────┘
关于 Cache-Control 和服务器端缓存之间的交互,我有很多问题(例如,应该Cache-Control: no-cache
,意味着服务器应该重新验证自己的缓存?)。但绝大多数归结为以下几点:
服务器端是否应该使用请求中的 Cache-Control 和其他相关标头来获取有关其服务器端缓存的逻辑?
以下面这个小(虽然很粗糙)的 Python Flask 应用程序为例:
@app.route('/app/<id>')
def endpoint(id):
if 'no-store' not in request.headers['Cache-Control']:
# If 'no-store' isn't specified, try cache first
entry = entry_cache.get(id)
if entry is None:
entry = service.get_entry(id)
else:
# Otherwise, immediately talk to the service
entry = service.get_entry(id)
return entry
此外,这引发了另一个问题,根据答案,可能会使上述问题变得无关紧要:
服务器端应该做什么样的缓存?什么情况下我们应该依赖 HTTP 缓存并计算每个请求的响应(除了类似的情况If-None-Match
)?
就上下文而言,我倾向于开发的大多数应用程序都设计为微服务,或者作为容器或作为具有缓存的无服务器功能,这些缓存往往是对外部服务(如 Redis)的调用。没有多少浏览器调用这些 HTTP 端点;大多数客户端是业务应用程序。
更新 (2021-08-17):感谢 Kevin 的反馈!我更新了图表和一些措辞,以澄清我专门指的是请求缓存标头而不是响应标头。此外,我添加了一个非常小(而且非常粗略)的 Python Flask 应用程序来帮助说明我所指的逻辑类型。
解决方案
HTTP 缓存规范不绑定服务器的内部缓存行为。根据定义,服务器的响应是新鲜的,无论它是如何生成的。因此,虽然中间代理使用指令为请求提供缓存响应是违反协议的no-cache
,但对于服务器本身却不是这样。
也就是说,协调两种缓存当然是可能的,无论是隐式(响应碰巧设置了缓存请求标头的请求)还是显式(定义您的 API 以使用 HTTP 缓存标头进行内部行为)。所以你的 Flask 例子对我来说很有意义。也就是说,我不熟悉在缓存代理之外使用这些请求标头的站点或框架,因此您可能是这方面的开拓者。
推荐阅读
- graphql - 运行 graphql deploy 时出现 Sanity groupProblems.js 错误
- java - Thymeleaf:列表的逗号分隔值?
- python - 如何将 python 的 datetime.tzinfo 对象转换为钟摆的 Timezone 对象?
- java - Quarkus Image:无法运行程序“keytool”:错误=2,没有这样的文件或目录
- php - WAMP 服务器 PhpMyAdmin 未使用有效凭据进行身份验证
- function - Kusto 功能错误 - 发生识别错误
- javascript - 指纹js指纹.get不是一个函数
- spamassassin - SpamAssassin 和 Spamhaus SBL 的组合错误地将带有公司链接的电子邮件标记为垃圾邮件
- python - 根据不同列表中的值过滤python列表
- javascript - React 单元测试 Jest 历史推送