Nginx 防盗链与缓存冲突问题及解决方案

VFX大学 Linux/macOS 与自动化运维 Nginx 防盗链与缓存冲突问题及解决方案

  • 该话题为空。
正在查看 0 条回复
  • 作者
    帖子
    • #1029

      追光
      管理员

      一份完整、可直接分享的防盗链 + 缓存冲突日志示例文章,方便在开发者社区发布,包含问题描述、原因分析、解决方案和示例 Nginx 配置。以下内容是实操记录:


      Nginx 防盗链与缓存冲突问题及解决方案

      在使用 Nginx 对静态资源(CSS/JS/图片等)进行防盗链和缓存控制时,经常会遇到一个坑:防盗链配置覆盖了你原本的缓存设置。如果不注意,CSS/JS 缓存可能会变成 30 天,而你本想设置为 1 小时。

      本文整理了一个完整示例,帮助大家避坑。


      1. 问题描述

      你可能会有类似如下配置:

      # 防盗链配置
      location ~ .*\.(jpg|jpeg|gif|mp4|mp3|png|js|css)$ {
          expires      30d;
          valid_referers none blocked *.baidu.com *.wx.qq.com *.taobao.com *.newvfx.com;
          if ($invalid_referer){
             return 404;
          }
      }
      
      # CSS/JS 缓存 1 小时
      location ~ .*\.(js|css)?$ {
          expires      1h;
      }

      结果

      • CSS/JS 资源实际缓存为 30 天,而不是预期的 1 小时。

      • 因为 Nginx 会匹配第一个符合的 location,CSS/JS 被防盗链块“抢走”,导致你设置的 1 小时缓存失效。


      2. 原因分析

      1. Nginx 匹配规则:正则 location 按照配置顺序匹配,第一个匹配的规则生效。

      2. 防盗链和缓存冲突:防盗链 block 里 expires 30d 覆盖了后面的 1 小时缓存设置。

      3. H3 Engine / 自定义 Nginx 逻辑:某些内置逻辑可能默认生成长时间缓存,也会加大混淆。


      3. 解决方案

      方案 A:在防盗链块里增加专用日志

      方便排查哪些资源走了防盗链规则,同时不影响原有缓存策略:

      #SECURITY-START 防盗链配置
      location ~ .*\.(jpg|jpeg|gif|mp4|mp3|png|js|css)$ {
          expires 30d;  # 防盗链默认缓存
          access_log /www/wwwlogs/security_referer.log combined;  # 专用日志
      
          valid_referers none blocked *.baidu.com *.wx.qq.com *.taobao.com *.newvfx.com *.jd.com;
          if ($invalid_referer){
             return 404;
          }
      }
      #SECURITY-END

      每次资源匹配到防盗链规则时,都会写入 security_referer.log,方便排查和统计。


      方案 B:统一 CSS/JS 缓存,不受防盗链影响

      如果你希望 CSS/JS 都走 1 小时缓存,可以在防盗链块中覆盖:

      location ~ .*\.(js|css)$ {
          expires 1h;
          add_header Cache-Control "public, max-age=3600" always;
          access_log /www/wwwlogs/security_referer.log combined;
          valid_referers none blocked *.baidu.com *.wx.qq.com *.taobao.com *.newvfx.com *.jd.com;
          if ($invalid_referer){
             return 404;
          }
      }
      • expires 1h + Cache-Control 明确覆盖原 30 天缓存。

      • 防盗链依然生效。

      • 日志记录所有命中情况,方便监控。


      方案 C:最佳实践建议

      1. 防盗链和缓存分开:图片/视频走防盗链缓存;CSS/JS 单独设置缓存。

      2. 使用专用日志:方便统计防盗链命中情况。

      3. 遵循 Nginx location 顺序规则:正则 location 优先匹配顺序,容易导致意外覆盖。

      4. 测试工具:使用 curl -I URL 检查 Cache-Control / Expires 是否生效。


      4. 测试示例

      curl -I https://www.newvfx.com/wp-content/themes/newvfx-child/style.css

      输出示例(CSS 1 小时缓存):

      HTTP/2 200
      Cache-Control: max-age=3600
      Expires: Tue, 26 Aug 2025 07:48:13 GMT

      输出示例(图片防盗链 30 天缓存):

      HTTP/2 200
      Cache-Control: max-age=2592000
      Expires: Thu, 25 Sep 2025 06:30:00 GMT

      ✅ 总结:

      防盗链和缓存控制是常见组合,但 Nginx 默认规则容易导致 CSS/JS 缓存被覆盖。通过日志记录 + 明确 expires/Cache-Control,可以安全避开“30 天缓存”陷阱。

正在查看 0 条回复
  • 在下方一键注册,登录后就可以回复啦。