HTTP之防盗链

很多时候别人直接把我们的网站的资源拿去在他们网站展示,但是消费的是我们的流量,为了解决这种问题,才会有防盗链这个思路

这里说的只是一个简单的概念,既使用host和reffer请求头做对比,简单的做一个处理,主要是用来熟悉http头

这里就是代码

// 防盗链实现
//  这里主要是通过reffer和host做对比,如果不是当前域,则给一张无用的图片
// 实现读取
let fs = require('fs')
let path = require('path')
let url = require('url')

/**
 * @description 解析host
 * @param {string} referStr 需要解析的refer字符串
 */
let getHostName = referStr => {
    let { hostname } = url.parse(referStr)
    return hostname
}
const server = require('http').createServer((req, res) => {
    // 拿到refer
    let refer = req.headers['referer'] || req.headers['referrer']

    // 判断是否又refer,有可能没有refer
    // 读取文件,返回给浏览器
    let { pathname } = url.parse(req.url)
    // p代表我们要找的文件
    let p = path.join(__dirname, 'public', '.' + pathname) // 这里是请求文件

    // 判断请求的文件有没有,没有的话直接结束,有的话在读取文件
    fs.stat(p, err => {
        if (!err) {
            if (refer) {
                // 先看一下refer的值,还要看图片的请求路径
                let referHostName = getHostName(refer)
                let host = req.headers['host'].split(':')[0]

                if (referHostName != host) {
                    // 防盗链
                    fs.createReadStream(path.join(__dirname, 'public', './timg.jpeg')).pipe(res)
                } else {
                    // 正常展示
                    fs.createReadStream(p).pipe(res)
                }
            } else {
                // 正常展示
                fs.createReadStream(p).pipe(res)
            }
        } else {
            res.end()
        }
    })
}).listen(5000)

// 当服务器错误时调用
server.on('error', err => {
    if (err.code == 'EADDRINUSE') server.listen(++port)
    if (err) console.log(err)
})

// 当服务器关闭时调用
server.on('close', () => {
    console.log('服务端关闭')
})

白名单

很多时候我们做了限制以后,有需要给某些网站给引用的权限,就是白名单

// 添加白名单,可以允许某个站点访问当前站点
// 防盗链实现
//  这里主要是通过reffer和host做对比,如果不是当前域,则给一张无用的图片
// 实现读取
let fs = require('fs')
let path = require('path')
let url = require('url')

/**
 * @description 解析host
 * @param {string} referStr 需要解析的refer字符串
 */
let getHostName = referStr => {
    let { hostname } = url.parse(referStr)
    return hostname
}

// 白名单
let whiteList = ['www.demo.com']
const server = require('http').createServer((req, res) => {
    // 1拿到refer
    let refer = req.headers['referer'] || req.headers['referrer']

    // 判断是否又refer,有可能没有refer
    let { pathname } = url.parse(req.url)
    // p代表我们要找的文件
    let p = path.join(__dirname, 'public', '.' + pathname) // 这里是请求文件

    // 判断请求的文件有没有,没有的话直接结束,有的话在读取文件
    // 读取文件,返回给浏览器
    fs.stat(p, err => {
        if (!err) {
            if (refer) {
                // 先看一下refer的值,还要看图片的请求路径
                let referHostName = getHostName(refer)
                let host = req.headers['host'].split(':')[0]
                // 这里判断, referHostName != host
                // 白名单 加入判断 !whiteList.includes(referHostName)
                if (referHostName != host && !whiteList.includes(referHostName)) {
                    // 防盗链
                    fs.createReadStream(path.join(__dirname, 'public', './timg.jpeg')).pipe(res)
                } else {
                    // 正常展示
                    fs.createReadStream(p).pipe(res)
                }
            } else {
                // 正常展示
                fs.createReadStream(p).pipe(res)
            }
        } else {
            res.end()
        }
    })
}).listen(5000)
// 当服务器错误时调用
server.on('error', err => {
    if (err.code == 'EADDRINUSE') server.listen(++port)
    if (err) console.log(err)
})

// 当服务器关闭时调用
server.on('close', () => {
    console.log('服务端关闭')
})

最后的目录结构

// demo/public/index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>防盗链</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" type="text/css" media="screen" href="main.css" />
  <script src="main.js"></script>
</head>
<body>
  <!-- 服务端不支持 ./ ../ 如果写了,相当于 ./ || ../  => / -->
  <img src="http://www.test.com:5000/xiaoxin.jpg" alt="test">
</body>
</html>

// 图片,如我的两张图片
// demo/public/xiaoxin.jpg
// timg.jpg //这个为用户调用我们的链接时候返回的图片

// server 脚本
// demo/server.js 内容就是上边的代码

// 测试 因为需要多个URL地址,所以需要自己去host设置一下,才能实现,如我的设置
// 127.0.0.1 www.demo.com 
// 127.0.0.1 www.test.com

//做完上述设置,就可以在浏览器进行测试了
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值