什么是 “盗链”?

“盗链” 说白了就是利用别人网站的资源链接放在自己的站点,在未经允许的情况下去获取别人网站里面的图片或者视频等资源,导致资源所有者的网站的流量费用增加或收入减少,为了防止资源链接随意被人盗用的手段被称为 “防盗链”。

模拟 “盗链” 场景

我们先来模拟一下 “盗链” 场景,在本地启动服务运行 hotlinking.html 文件,并在文件中盗用百度视频的图片资源,看看效果。

文件:hotlinking.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>盗链</title>
</head>
<body><img src="http://c.hiphotos.baidu.com/video/pic/item/e61190ef76c6a7ef8891a7c9f1faaf51f2de66ad.jpg">
</body>
</html>复制代码

我们通过 http-server 来启动服务器访问 hotlinking.html,使用 http-server 需全局安装。

http-server install -g

在服务中打开 hotlinking.html 后我们发现图片并不是我们盗用链接的资源,而是变成了下面这张图片。

这张图用来提醒我们盗用了别人资源,是因为百度的服务器做了防盗链处理,如果所有盗用别人的资源都变成这样,盗用也就没有实际意义了,我们本篇就通过 NodeJS 来实现防盗链处理,用来保护自己站点的资源。

注意:具备防盗链处理的网站的资源链接可以直接通过浏览器地址栏访问,也可以在文件域(file 协议)访问,限制的是在未经允许的情况下其他服务器的访问。

NodeJS 服务器实现防盗链

1、模拟两个域名

在本地的 hosts 文件中加入两个域名:

127.0.0.1          panda.com
127.0.0.1          shen.com

2、准备图片资源

在根目录创建文件夹 public 并存入两张图片,success.png 是正常请求的图片资源,error.png 是经过防盗链处理后返回的图片资源,两张图片如下。

正常返回的图片资源 success.png:

防盗链处理后返回的图片资源 error.png:

3、页面 index.html

在页面当中通过 img 标签分别访问 shen.com、panda.com 和 localhost 域下的 success.png 文件。

文件:index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>盗链</title>
</head>
<body><img src="http://panda.com:3000/success.png"><img src="http://shen.com:3000/success.png"><img src="http://localhost:3000/success.png">
</body>
</html>复制代码

4、服务端 server.js

在写服务端代码之前需要介绍两个重要的请求头:

  • host:资源所在的域
  • referer:请求来源的域

其实资源防盗就是设置白名单,通过检测 referer 是否在白名单中,如果在则正常返回资源,不存在则返回经过防盗链处理的资源。

注意:referer 请求头在地址栏输入地址时发送的请求是不存在的(如请求 index.html 页面),在旧版本的 HTTP 协议中 referer 的写法为 referered,所以为了兼容旧版本协议应该做兼容处理。
文件:server.js
// 引入依赖
const http = require("http");
const url = require("url");
const path = require("path");
const fs = require("mz/fs");const server = http.createServer(responseImages); // 创建服务器
let static = path.resolve(__dirname, "public"); // 静态资源目录
let whiteList = ["shen.com"]; // 白名单async function responseImages(req, res) {// 解析 url 中的文件目录处理成绝对路径let p = path.join(static, url.parse(req.url).pathname);// 检测文件路径是否合法,不合法直接返回 Not Foundlet isExist = await fs.exists(p);if (isExist) {// 获取 refererlet refer = req.headers["referer"] || req.headers["referered"];// 存在 referer 继续检测if (refer) {// 请求资源存在 referer,做防盗链处理let referHost = url.parse(refer).hostname;let host = req.headers["host"].split(":")[0];// 当访问源的域和资源所在的域不是同一个域,做防盗链处理if (referHost !== host) {let isInWhiteList = whiteList.includes(refer);p = isInWhiteList ? p : path.join(static, "error.png");}}// 第一次访问请求页面 index.html,不存在 referer,将静态资源返回// 第二次访问请求图片资源,如果 referer 和资源所本就是同一个域,直接将资源返回fs.createReadStream(p).pipe(res);} else {res.statusCode = 404;res.end("Not Found");}
}server.listen(3000, () => {console.log("server start 3000");
});复制代码

其实上面的服务器是 shen.com、panda.com 和 localhost 所共用的,只是通过不同的域名访问。

启动服务器,然后通过 localhost:3000 访问,此时由于与 shen.com 和 panda.com 为不同域,所以只有第三张图片返回 success.png

通过 shen.com:3000 访问,由于存在白名单中,所以三张图片都返回 success.png

通过 panda.com:3000 访问,由于 shen.com 在不同域,所以没有返回 success.png

无论通过 shen.com 还是 panda.com 访问 localhost 的资源都是在同域的,所以都能获取到。

总结

在上面我们利用本地服务实现了一个最基本的防盗链,思路就是 referer 与资源同域,正常返回,不同域检测白名单,在真实的开发场景可能会更细化,更复杂一些,其实整个防盗链实现的核心就是利用 HTTP 的 refererhost 请求头做检测,希望通过本篇的学习,大家可以对资源防盗链有所了解,并在后面开发类似功能时提供思路。

基于NodeJS的HTTP server Plus 2:防盗链(referer)相关推荐

  1. html设置referer防盗链,referer与防盗链

    referer是什么 referer 中文意思是:参照页面,引用页. 下图直观感受,(づ ̄ 3 ̄)づ image 直接在浏览器中输入url地址来直接访问图片/js/css等资源时是没有referer的 ...

  2. 单机十万并发HLS直播服务器的防盗链技术

    单机十万并发HLS直播服务器的防盗链技术 本文主要介绍基于HLS直播服务器的十万并发防盗链实现 录制切片服务器 HTTP 服务器 (nginx) LuaLib 录制切片服务器 录制切片服务器负责把直播 ...

  3. 基于Nodejs的前端灰度发布方案_20190228

    基于Nodejs的前端灰度发布方案 1. 灰度发布和A/B测试简介 灰度发布 将某个功能灰度发布(逐渐放量)给特定线上人群,避免新功能全量上线带来的风险. 上面的图可以通过两个方面来理解: 蓝色实线和 ...

  4. 基于ASP.NET+SQL Server实现(Web)企业进销存管理系统【100010296】

    企业进销存管理系统的设计和实现 ​ 一.摘要 进销存管理是现代企业生产经营中的重要环节,是完成企业资源配置的重要管理工作,对企业生产经营效率的最大化发挥着重要作用.本文以我国中小企业的进销存管理为研究 ...

  5. node php聊天室,利用socket.io实现多人聊天室(基于Nodejs)

    利用socket.io实现多人聊天室(基于Nodejs) socket.io简介 在Html5中存在着这样的一个新特性,引入了websocket,关于websocket的内部实现原理可以看这篇文章,这 ...

  6. 基于nodejs爬虫程序下载

    node-crawler 一个基于nodejs的网站采集服务器 可部署在任何服务器上远程调用 DEMO 发送请求 run npm dev POST: /scan {"url": & ...

  7. 搭建基于 nodejs 的 MQTT 服务器

    创建服务端 1.先从初始化一个 package.json 开始. npm init 2.安装 mqtt 服务器必要依赖项 mosca mqtt npm install mosca mqtt 3.根目录 ...

  8. Sequelize 4.43.0 发布,基于 Nodejs 的异步 ORM 框架

    Sequelize 4.43.0 发布了,Sequelize 是一款基于 Nodejs 的异步 ORM 框架,它同时支持 PostgreSQL.MySQL.SQLite 和 MSSQL 多种数据库,很 ...

  9. 基于群集的Hyper-v Server副本

    基于群集的Hyper-v Server副本 前面的博文中和大家聊了Hyper-v副本,相信大家对Hyper-v副本已经有了一个大致了解!今天我们就来给大家介绍一下基于群集的Hyper-v Replic ...

最新文章

  1. JMessage Android 端开发详解
  2. 关于一个枚举IE表单的DLL,编译无错,但是得不到想到的结果。
  3. 解决在非Activity中使用startActivity
  4. 【转】1.SharePoint服务器端对象模型 之 对象模型概述(Part 1)
  5. 10分钟教会你Apache Shiro
  6. python循环绘制六角星_《Python游戏趣味编程》 第3章 美丽的圆圈画
  7. Oracle 10g 高级安装图文教程(一)
  8. Java程序员校招蚂蚁金服,大专生出身,做Java程序员真的没有春天吗
  9. QTP引用外部脚本路径的设定(二)left函数的使用
  10. HTTP请求报文分析
  11. 阿文PPT教程视频课程2019送PPT模板 我懂个P
  12. python wps et_使用Python操作XLS文件(wps中叫et)
  13. html页面背景图片不够大怎么办,Word背景图片不够大怎么办
  14. 解决Chrome浏览器主页被hao123、360和2345篡改简单有效方法
  15. Python网络爬虫反爬破解策略实战
  16. LLS2000 智能多通道信号控制采集器
  17. 自协方差函数的Matlab实现
  18. JavaScript object移除
  19. 弄清楚这个三角关系,工作效率提高50%
  20. 如何解决青年大学习的复制粘贴问题???

热门文章

  1. EF ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象...
  2. Windows程序中的Lib和Dll文件
  3. # [银联复赛]-整数对:数论
  4. sublime与python交互
  5. 【洛谷习题】尼克的任务
  6. HDU——1272小希的迷宫(并查集+拓扑排序)
  7. WinForm里ListBox实现加入项目,并且排序。
  8. DeepFaceLab报错,CUDA driver is insufficient 解决方法!
  9. 【回顾】推荐系统工程师技能树
  10. ICML 2019 | 强化学习用于推荐系统,蚂蚁金服提出生成对抗用户模型(附论文下载链接)...