防盗链必须由Nginx实现,Layui前端无法可靠拦截;需精准配置location匹配静态资源路径,结合valid_referers白名单(含none、各子域及CDN域名),并对敏感资源启用secure_link签名验证。

Layui 本身不参与防盗链,所有防盗链逻辑必须由 Nginx 完成;Layui 引用的 layui.css、layui.js、图标字体、默认 loading 图等静态资源,只要被外部网站直接 `` 或 `<script>` 引入,就面临盗链风险——你得在 Nginx 里把它们“圈住”,而不是指望前端框架做拦截。</script>
为什么不能在 Layui 前端加 referer 判断
浏览器禁止 JavaScript 读取当前请求的 Referer 请求头(出于安全限制),document.referrer 只能读上一页来源,且可被伪造或清空。任何试图用 if (document.referrer.indexOf('yourdomain') === -1) 动态阻断 layui.js 加载的行为,既不可靠,又会破坏自身页面初始化——Layui 的模块加载器(layui.use)依赖脚本顺序执行,中途中断会导致整个 UI 失效。
所以:防盗链不是前端的事,是 Nginx 必须承担的边界职责。
匹配 Layui 静态资源的 location 要写准
Layui 默认资源路径集中、后缀明确,但容易误配成全局正则,导致 HTML 页面或 API 接口也被卷入校验。必须用精准、高效的方式锁定资源范围:
-
location ^~ /static/layui/—— 如果你把 Layui 放在/static/layui/下,这是最推荐的写法:前缀匹配、无正则开销、优先级高 -
location ~* \.(js|css|woff2|ttf|png|gif)$—— 若资源混放,需加上^~ /static/前缀约束,否则可能匹配到/api/user.png这类非静态接口返回的图片 - 千万别写
location /或location ~ \.js$顶层规则——它会干扰index.html的正常访问,甚至让nginx -t报错“duplicate location”
同时确保该 location 内有 alias 或 root 指向真实文件目录,例如:alias /var/www/static/layui/;,否则 Nginx 找不到 layui.js,防盗链还没起作用,资源先 404 了。
valid_referers 白名单必须包含 layui 页面的真实来源
Layui 页面常以单页形式部署,用户可能从 https://example.com/、https://admin.example.com/、https://app.example.com/ 等多个子域加载资源;也可能通过 HTTPS 页面跳转到 HTTP 的静态资源(触发 Referer 清空),或用微信内置浏览器打开(部分版本清 Referer)。白名单漏掉任一场景,都会导致自己页面白屏或样式错乱:
- 必须包含
none:允许地址栏直输/static/layui/layui.css、微信分享卡片预览、小程序 WebView 直接加载 CSS - 必须显式列出所有主域和子域:
example.com www.example.com admin.example.com app.example.com——*.example.com不匹配example.com本身 - 若使用 CDN 回源,CDN 的回源 IP 请求带的是它自己的域名(如
cdn-xx.cloudflare.net),需把 CDN 域名也加进白名单,或用blocked兼容其清 Referer 行为
典型配置示例:
location ^~ /static/layui/ {
alias /var/www/static/layui/;
valid_referers none blocked example.com www.example.com admin.example.com *.cdn-provider.net;
if ($invalid_referer) {
return 403;
}
}防绕过:别只拦 Referer,关键资源加 secure_link
单纯靠 valid_referers 拦不住批量爬虫或恶意构造请求——curl -H "Referer: https://example.com/" 一行就能绕过。对 Layui 中可被下载的敏感资源(比如你放在 /static/layui/download/ 下的定制版压缩包、PDF 文档、或私有图标集),必须启用 secure_link 模块做签名验证:
- 后端生成带签名的 URL:
/static/layui/download/lite-v2.8.18.zip?md5=abc123&expires=1720512000 - Nginx 校验逻辑写在独立
location中:secure_link $arg_md5,$arg_expires;+secure_link_md5 "your_secret_key$uri$arg_expires"; - 签名 URL 有效期建议设为 1–6 小时,避免长期泄露;过期返回
410 Gone,比403更明确表示“资源已失效”
这个动作无法由 Layui 自动完成,必须由你的后端服务(PHP/Node.js/Java)在渲染页面时动态拼接签名链接,并注入到 <a href="..."> 或 layui.download 调用中。
真正难的不是写对一行 valid_referers,而是想清楚:哪些资源必须严格保护,哪些可以宽松兼容;哪些请求来自真实用户(哪怕 Referer 为空),哪些明显是脚本批量拉取——Nginx 配置只是执行者,判断依据全在你对业务流量的理解里。



















