缓存键漏掉协议会导致http/https请求命中同一缓存条目,引发内容混淆、跳转异常、混合内容警告及安全降级;须通过curl对比age/x-cache、检查proxy_cache_key是否含$scheme、验证cdn缓存哈希隔离性,并强制在缓存键中显式包含协议字段。

缓存键漏掉协议(http vs https)会导致同一资源在不同协议下命中同一个缓存条目,引发内容混淆、跳转异常、混合内容警告甚至安全降级。这不是小概率事件——尤其在反向代理、CDN 或多端统一缓存架构中很常见。
确认是否因协议缺失导致缓存混淆
先验证问题是否存在:
- 用
curl -I http://example.com/api/data和curl -I https://example.com/api/data分别请求,对比响应头中的Age、X-Cache(或自定义缓存标识头)是否一致;若一致,说明缓存键未区分协议 - 检查 Nginx/Apache 的
proxy_cache_key或CacheKey配置,看是否显式包含$scheme(Nginx)或%{HTTPS}s(Apache) - 抓包或查 CDN 日志,观察不同协议请求是否生成相同缓存哈希值(如 Cloudflare 的
cf-cache-status同为 HIT,但原始请求协议不同)
修复缓存键:必须显式携带协议信息
协议是缓存上下文的关键维度,不加它等于默认“所有协议等价”,而现实中 http 和 https 的响应可能完全不同(如重定向逻辑、HSTS 头、Cookie 的 Secure 标志)。
- Nginx 示例(推荐):
proxy_cache_key "$scheme$request_uri $cookie_sessionid $http_authorization";
注意:不能只写$request_uri,它不含协议;$scheme是必需项 - Apache 示例:
CacheKey "%{HTTPS}s://%{HTTP_HOST}s%{REQUEST_URI}s"
确保%{HTTPS}s参与计算,值为on或off - 后端代码中生成缓存键时,也要把
scheme(如req.protocol或req.headers['x-forwarded-proto'])作为输入参数,避免仅依赖路径和查询参数
验证修复效果的实操步骤
改完配置后,不能只测“能缓存”,要专测“协议隔离”:
- 分别用
http和https请求同一接口,观察首次响应后,第二次请求是否各自独立缓存(即Age从 0 开始累加,而非共享) - 对返回 301/302 跳转的接口,特别检查跳转目标 URL 是否正确带协议(比如
http请求不该跳到https页面再被缓存,反之亦然) - 在浏览器 DevTools 的 Network 面板中,切换协议访问,查看
Size列:若都是from disk cache且时间戳接近,说明仍共用缓存;理想状态是各自首次加载走网络,后续才缓存
连带风险:协议混淆常伴生 Cookie 和 Header 错乱
漏协议不只是缓存错,还可能放大其他问题:
- 当
http请求命中了之前https下缓存的响应,而该响应设置了Set-Cookie; Secure,浏览器会直接丢弃这个 Cookie,导致登录态丢失 - 某些中间件根据
$scheme注入不同 Header(如X-Forwarded-Proto),缓存键不包含它,就可能把本该给 HTTPS 的响应错发给 HTTP 客户端 - API 接口若返回协议敏感内容(如 Webhook 回调地址拼接),缓存混淆会导致下游收到错误协议的 URL











