https下防盗链仍有效,但需白名单显式包含https://域名或正则匹配https?://,确保cdn回源、反向代理透传referer,并兼容微信等客户端referer丢失场景。

全站启用 HTTPS 后,防盗链依然能生效,但必须注意 Referer 字段在跨协议跳转时的丢失问题——HTTP 页面引用 HTTPS 资源时,浏览器会主动清空 Referer;而 HTTPS 页面引用 HTTPS 资源则正常携带。所以问题不在于 HTTPS 本身破坏防盗链,而在于混合来源、跨域调用或 Referer 策略变更导致白名单匹配失败。
确保 valid_referers 白名单兼容 HTTPS 协议
Referer 头在 HTTPS 页面中始终以 https:// 开头,因此白名单必须显式支持 HTTPS 域名,不能只写 example.com 或 *.example.com(Nginx 默认不自动补协议)。正确写法包括:
-
https://example.com和https://www.example.com(分开写更稳妥) -
~^https?://(www\.)?example\.com$(正则匹配 HTTP/HTTPS + www/非www) -
server_names仍有效,但需确保server_name包含 HTTPS 对应的域名(如server_name example.com www.example.com;) - 合作方域名务必带上
https://前缀,例如https://partner-site.com https://cdn.partner.net
处理跨域图片请求的 Referer 兼容性
当其他 HTTPS 站点(如 https://blog.trusted.com)合法嵌入你的图片时,其 Referer 是完整 HTTPS 地址。若你只写了 *.trusted.com,Nginx 不会匹配成功(该语法仅匹配子域名,不含协议和路径)。建议:
- 对可信第三方,用明确的
https://blog.trusted.com而非模糊通配 - 若合作方有多个子域,用正则:
~^https?://([a-z0-9\-]+\.)?trusted\.com$ - 避免依赖
blocked——它适用于 Referer 存在但被截断为非 http(s) 开头的场景(如内网代理),不解决跨域协议问题
避免因 CORS 与防盗链冲突导致误拦截
前端通过 JS 的 fetch 或 XMLHttpRequest 加载图片时,若启用了 credentials: true,浏览器会发送 Origin 头而非 Referer;此时防盗链规则完全不触发。但普通 <img src="..."> 标签始终发 Referer,不受影响。需注意:
- 防盗链只作用于 Referer 检查,不替代 CORS 配置;跨域图片展示本身不需要 CORS,只有 JS 读取图片二进制内容才需要
- 不要在防盗链 location 中错误添加
add_header Access-Control-Allow-Origin "*";——这不会让防盗链放行,反而可能暴露资源给非法跨域脚本 - 若业务确需 JS 动态加载并解析图片(如 canvas 处理),应改用后端代理或带签名的临时 URL,而非依赖 Referer 防盗链
验证与调试关键点
HTTPS 环境下防盗链失效,常见原因不是配置错,而是测试方式不对:
- 用
curl -e "https://example.com" https://yoursite.com/img/test.jpg测试,而非http://协议的 Referer - 检查浏览器开发者工具 Network 面板,确认请求头中
Referer:确实存在且值符合预期 - 在
if ($invalid_referer)块中临时加日志:access_log /var/log/nginx/referer_debug.log main if=$invalid_referer;,观察哪些请求被误判 - 特别留意微信、钉钉等 App 内 WebView:它们常清 Referer 或设为
about:blank,应保留none选项











