nginx防盗链需在缓存前生效,valid_referers必须置于location最前端;禁止缓存403响应,合法资源可设长缓存但需etag配合;应按资源类型分location隔离配置,避免逻辑冲突。

静态资源防盗链和浏览器缓存本身不直接冲突,但配置不当容易引发逻辑矛盾——比如缓存了被防盗链拦截后返回的 403 响应,或缓存策略覆盖了防盗链判断所需的请求头校验时机。关键在于让缓存行为与防盗链逻辑协同工作,而不是相互干扰。
防盗链必须在缓存决策之前生效
Nginx 的处理顺序决定了:如果启用了 proxy_cache 或对响应做了强缓存(如 expires max),而防盗链规则写在缓存之后的位置,就可能把 403 错误也缓存下来,导致合法 Referer 后续请求仍被拒。
- 确保
valid_referers和$invalid_referer判断放在location块最前端,早于任何缓存指令 - 避免在已启用
proxy_cache的 location 中混用if ($invalid_referer)—— Nginx 官方明确不建议在缓存上下文中使用if - 推荐做法:对防盗链资源单独划分
location,不走反向代理缓存,只做本地文件服务 + 防盗链 + 简单 expires
缓存策略要适配防盗链的语义
防盗链不是永久性拒绝,而是按请求来源动态决策。因此缓存头不应暗示“该资源永远不可用”,否则浏览器或 CDN 可能长期复用错误响应。
- 禁止对 403 响应设置长缓存:在防盗链拦截分支中显式禁用缓存,例如
add_header Cache-Control "no-store, no-cache, must-revalidate" - 对合法资源,缓存时间可设长(如
expires 1y),但需配合ETag或Last-Modified,确保内容更新后能被正确刷新 - 若使用
proxy_cache缓存后端资源,应在proxy_cache_valid中排除 403 状态码:proxy_cache_valid 200 304 1y; proxy_cache_valid 403 1s;
区分资源类型,隔离配置作用域
同一 server 块下混合配置易出错。应按资源用途拆分 location,避免防盗链规则被其他缓存策略覆盖。
- 图片、字体、音视频等高盗链风险资源:用独立正则匹配,启用
valid_referers+ 短期缓存或无缓存 - CSS/JS 等前端逻辑资源:若允许跨域引用(如微前端),可放宽 Referer 限制,同时设置长缓存 + 版本哈希路径
- HTML 页面本身:通常不防盗链,但应设置短缓存(如
expires 10m)并启用ETag协商
验证是否真正生效
仅看配置是否语法正确不够,需确认实际响应头与行为符合预期。
- 用
curl -I https://yoursite.com/image.jpg -e "https://badsite.com"检查是否返回 403 且带Cache-Control: no-store - 再用
-e "https://yoursite.com"测试是否返回 200 并含Cache-Control: max-age=31536000 - 查看响应头中是否有
X-Cache-Status(若启用 proxy_cache),确认未缓存拦截响应











