必须包含$scheme和$host,是为了隔离不同协议和域名的缓存,避免开发环境与生产环境响应互相覆盖,确保http://dev.example.com和https://prod.example.com同路径请求生成独立缓存条目。

缓存键里加入请求协议($scheme)和主机名($host),最直接的作用就是让不同环境的响应互不干扰——比如 http://dev.example.com 和 https://prod.example.com 即使请求路径完全一样,也会生成两个独立的缓存条目。
为什么必须包含 $scheme 和 $host
很多团队在测试环境和生产环境共用同一套 Nginx 配置,但后端返回的内容可能不同:开发环境返回调试信息、Mock 数据或未压缩资源,而生产环境返回精简版、带 CDN 域名的链接或真实用户数据。如果缓存键只用 $request_uri,就可能出现:
- 用户在 HTTPS 生产站访问
/api/user,Nginx 缓存了带真实头像 URL 的响应; - 随后开发人员用 HTTP 访问同一路径做调试,Nginx 错误地返回了之前缓存的生产响应;
- 结果是开发看到“线上数据”,或用户看到“本地调试内容”,造成数据错乱或安全泄露。
标准写法与常见变体
推荐的基础缓存键配置如下:
这个组合已覆盖协议、域名、完整路径(含查询参数),适合绝大多数多环境部署场景。如需进一步区分,可考虑:
-
加请求方法:对 POST/PUT 等非幂等请求,默认不应缓存;若确需缓存(如某些只读 API),加上
$request_method可避免 GET 和 POST 冲突; -
排除特定查询参数:如
utm_source或ref这类仅用于追踪的参数,可用$args配合map指令清洗后再拼入缓存键,防止缓存碎片化; -
按子域名隔离:若
admin.example.com和www.example.com后端逻辑不同,$host已天然支持区分,无需额外处理。
验证是否生效的小技巧
上线新缓存键后,可通过以下方式快速确认:
- 在 Nginx 日志中启用
$upstream_cache_status,观察不同协议/域名下的请求是否分别命中HIT或各自MISSED; - 用
curl -I http://dev.example.com/a和curl -I https://prod.example.com/a对比响应头中的X-Cache-Status(需自定义日志格式); - 检查磁盘缓存目录下文件名哈希:Nginx 实际存储的文件名由缓存键 MD5 生成,不同
$scheme$host组合必然对应不同哈希前缀。











