referer 来源,表示这个资源被谁引用过,可以用来做防盗链。
我们新建文件 no-referer.js
const fs = require("fs"); const path = require("path"); const url = require("url"); const http = require("http"); http.createServer((req, res) => { const { pathname } = url.parse(req.url, true); const absPath = path.join(__dirname, pathname); fs.stat(absPath, (err, statObj) => { if (err) res.end("Not Found"); console.log("absPath----->", absPath); console.log("statObj----->", statObj); if (statObj) { console.log(statObj.isDirectory()); console.log(statObj.isFile()); if (statObj.isFile()) { fs.createReadStream(absPath).pipe(res); } else { res.end("Not Found"); } } else { res.end("Not Found"); } }); }).listen(3000);
新建文件 index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>凯小默测试图片防盗链</title> <!-- <meta name="referrer" content="never" /> --> </head> <body> <img src="http://127.0.0.1:3000/docker.jpg" alt="" /> </body> </html>
添加两张图片
启动服务:
nodemon no-referer.js
访问 http://127.0.0.1:3000/docker.jpg
,可以看到图片直接打开是不会增加 referer 的
我们另外用 live server 启动服务,访问 http://127.0.0.1:5500/doc/80/index.html
,我们可以看到图片的请求头加上了 referer
如果要实现引用我的人和我的域不是同一个,应该返回错误图片,我们应该进行校验
const fs = require("fs"); const path = require("path"); const url = require("url"); const http = require("http"); http.createServer((req, res) => { const { pathname } = url.parse(req.url, true); const absPath = path.join(__dirname, pathname); fs.stat(absPath, (err, statObj) => { if (err) return res.end("Not Found"); console.log("absPath----->", absPath); console.log("statObj----->", statObj); if (statObj) { console.log(statObj.isDirectory()); console.log(statObj.isFile()); if (statObj.isFile()) { // 只对图片进行防盗链,如果请求路径是 .jpg 结尾的需要判断引用的来源 if (/\.jpg/.test(absPath)) { let referer = req.headers["referer"] || req.headers["referrer"]; if (referer) { // 拿 host 跟 referer 比较 let host = req.headers.host; refererHost = url.parse(referer).host; console.log("host----->", host); console.log("refererHost----->", refererHost); if (host !== refererHost) { fs.createReadStream(path.resolve(__dirname, "referer.jpg")).pipe(res); return; } } } fs.createReadStream(absPath).pipe(res); } else { res.end("Not Found"); } } else { res.end("Not Found"); } }); }).listen(3000);
我们启动服务,访问 http://127.0.0.1:5500/doc/80/index.html
,我们可以看到 docker 的图片访问不了,而是展示了防盗的图片
nodemon referer.js
要展示 docker 图片的话,我们就应该去访问 访问 http://127.0.0.1:3000/index.html
,保证域相同
另外可以加上 meta 标签,不带 referer,如果网站没有 referer 会导致发送任何资源都不会带 referer
<meta name="referrer" content="never" />
注意:单词
referer
是错误的写法,正确的单词应该是referrer
,感兴趣可以看这篇:Referrer 还是 Referer?