一、能够用 浏览器请求时HTTP头的Referer字段的值php
复制网页的时候,里面的图片复制不下来,就是别人用了防盗链的方法html
做为普通的网民来讲,通常不须要知道也不用关心什么是盗链,不过若是你是网站的开发者或维护者,就不得不重视盗链的问题了。若是你刚刚开发完一个没有防盗链的带有文件下载功能的网站,挂上internet,而后上传几个时下很是热门的软件或电影并在网站内公布下载地址,让MSN上的全部好友都来体验一下你的杰做。web
不用多久就会发现网速出奇地变慢,甚至服务器托管中心的服务员会热情地打电话告诉你的网站流量很大,估计是网站受欢迎起来了,问你是否是该考虑加钱租用带宽更宽但价格更贵的网线了。在这个值得庆祝的时候赶快打开Google Analytics看看有多少人来光顾你的网站了吧,若是发现访客天天才十来我的,很遗憾地告诉你:你的网站资源不幸地被人盗链了。数据库
并且更糟糕的是,当你把网站上的文件和电影统统删光以后,网站仍然没有变快多少,从web服务器的访问日志里会发现疯狂的访问请求正从四面八方涌过来,web服务器为了迎接这批访客而没有时间处理正常的页面,这种情况可能会一直持续好几个周时间。apache
网站资源被盗链简单来讲就是别人不是从你的网站经过下载资源,被盗链的几种可能状况:windows
一、人气很是旺的网站、论坛、社区的网页里直接引用了(使用标记)你网站上的图片,或者直接在其余网页(使用flash或媒体播放插件)里嵌入了你网站上的mp3。浏览器
二、在人气很是旺的网站、论坛、社区里提供了你的资源的下载地址。服务器
三、你网站的资源可能被一些下载软件列入了“资源候选名单”,当其余人用下载工具下载相同的文件时,下载软件会自动找上门而且从你的服务器下载。cookie
既然被盗链的后果这么可怕,那有哪些方法能够防止盗链呢下面从简到繁总结一下常见的以及本身实践过的一些方法,并简单分析一下。不过很遗憾地,这些方法都无法彻底杜绝被盗链,而且防盗链的目的应该是从必定的程度上减小被盗链所产生的影响,同时能让合法的用户可以以天然的方式、顺畅地从你的网站下载资源。session
方法1:判断引用地址
这个方法是最先及最多见的方法。所谓判断引用地址,就是判断浏览器请求时HTTP头的Referer字段的值,这个值在asp.net里面能够用 Request.UrlReferrer属性取得。几个例子来讲,在正常状况下当用户在浏览 http://uushare.com/abc.html 时点击一个连接去到 http://uushare.com/jacky.mp3 文件时,浏览器在发出请求jacky.mp3 资源时还会附带当刻浏览器所处的页面地址(即http://uushare.com/abc.html),因此当你的网站程序接收到下载 jacky.mp3 资源请求的时候,先判断http的referer字段的值,若是是从 本身的域名(uushare.com)过来的,则能够认为是合法的链接请求,不然就返回一个错误的提示信息。
这种方法一般用于图片、 mp3这种容易被人用html“嵌入”到其余网站的资源,使用这种方法能够防止你的图片直接出如今别人的网页里(或者防止mp3直接被其余网站嵌入到 flash播放器里),不过访客使用下载工具仍是能够轻松下载,由于如今的下载工具通常会自动用你的域名构造一个引用地址,因此若是想再进一步防范的话,可使用一个对应表限制每一个资源的引用地址,例如将 jacky.mp3 的引用地址限制为 http://uushare.com/abc.htmlid=12345,这样下载工具就不太可能构造一个“正确”的引用地址了。
方法2:使用登陆验证
这个方法常见于论坛、社区。当访客请求网站上的一个资源时,先判断此请求是否经过登陆验证(在asp.net里经常使用session或form验证来记录登陆状态),若是还没有登陆则返回一个错误提示信息。使用这个方法还能够进一步判断登陆的用户的权限是否足够,以实现带“权限”的下载。
不过由于登陆状态依赖于会话id,而会话id每每储存于http请求的cookie字段里,下载工具通常无法得到浏览器的cookie字段,因此这些资源每每没法使用下载工具来下载,给正常合法用户带来诸多不便(由于大部分网民的系统都安装了下载工具,一点击下载连接通常会被下载工具拦截,致使没法使用浏览器自己的下载功能)。简单的解决方法是将这个session id放到URL中。
这种方法的另一个缺点是访客没法匿名下载,因此这个方法通常只用于论坛和社区网站。
方法3:使用cookie
其实这种方法原理上跟方法2差很少。就是在显示“下载”连接的页面里产生一个动态值的cookie,而后在处理资源下载请求时先判断cookie里有没有正确的cookie,若是没有则返回错误提示信息。至于这个动态值如何产生,只要能逆向判断动态值是否合法的均可以,例如将当前的时间去除秒数取哈希值(也叫散列值)。若是网页程序是asp.net则更简单,能够往Session里随便存一个字符串或数字,而后在处理下载请求时先检查Session 里是否存在这个字符串或数字。使用这个方法的缺点跟方法2同样。
方法4:使用POST下载
客户端浏览器请求资源都是使用HTTP的GET方法的,其实使用POST方法也能够往客户端返回数据。因此能够将下载连接换成一个表单(Form)和一个按钮(Submit),将待下载的文件的名称或id放到表单的一个隐藏文本框(Input)里,当用户点击提交按钮时,服务程序先判断请求是否为 POST方式,若是是则读取目标资源的二进制数据并写入响应对象(在asp.net里是respone.BinaryWrite方法)。
使用这个方法的缺点一样是没法使用下载工具,更无法实现断点续传。 不过比方法2,3好一点的是,下载工具不会拦截你的下载动做,因此正经常使用户仍是比较顺畅地下载到文件。这个方法比较适合小文件的下载。
方法5:使用图形验证码
使用这个方法能够保证每次下载都是“人”在你的网站上下载,而不是下载工具。由于网上不少介绍使用图形验证码的方法,因此这里就再也不重复了。这个方法的缺点是比较容易让正常的用户感到麻烦。
方法6:使用动态文件名
也叫动态钥匙法,当用户点击一个下载连接时,先在程序端计算一个Key(使用必定规律产生的Key,最好不要使用随机字符串例如GUID,而且这个 Key必须有必定时效的),而后在数据库或Cache里记录这个Key以及它所对应的资源ID或文件名,最后让网页重定向一个新的URL地址,这个新 URL地址里须要包含这个Key。当浏览器或下载工具发出下载请求时,程序先检测这个Key是否存在,若是存在则返回对应的资源数据。
使用这个方法的好处是下载工具也能够下载,而且在Key失效前能够断点续传,而且能够经过Key来控制下载的线程数。
使用这个方法(包括以上全部支持下载工具的方法)的缺点是:当任意一个用户下载成功以后,你的资源就会被一些下载工具列入“资源候选名单”,之后其余人在其余地方下载一样的文件时,下载工具会不断链接你的服务器,即便你的文件已经删除或者Key已经失效了,这样会形成类DDos攻击的后果,下面再介绍两个便可以让下载工具下载,又能够防止盗链的方法。
方法7:擅改资源的内容
通常热门的资源都是电影、mp三、较大的压缩包等,这些文件都是有不少能够插入数据的地方的,例如mp3有一个tag区,rar/zip有一个备注区,电影的内容随便一个地方,只要在下载过程中,动态地往这些地方注入一些随机的字节(几个字节便可),就能够达到让整个文件的哈希值(即散列值、指纹值)发生改变,让从你网站下载的文件的哈希值跟别人的不同,就能够防止下载工具主动找上门了。用这个方法配合方法6,能够达到较好的防盗链的效果。缺点是,虽然文件被修改的部分不会被“看”、“听”出来,不过多多少少让知道的人以为不爽。另外就是若是别人把从你网站下载的文件放到其余网站,那么仍然存在下载工具主动找上门的状况(虽然实际上它下载不了内容)。
方法8:打包下载
这个方法跟方法7的道理是同样的,只不过此次不是往原始文件里修改,而是在原始的文件基础上再加个“外壳”,让资源的哈希值跟别人的不同。使用这个方法能够在不擅改资源原始的内容基础上实现方法6一样的效果,而且狠一点的话,甚至能够在打包的时候放入本身的一些广告。缺点是用户每次下载都得加压缩,不过目前大部分人都懂得解压,因此这个缺点有时能够忽略不计。
仅供HTTP协议的初学者了解。
使用HTTP协议。利用referer作防盗链(不须要用php编写,而是在服务器层面控制就OK了)
咱们在网页里访问站外的图片的时候,在图片本站是能够看得,在外头就不能看了
由于header信息中的referer元素。
还有是作统计的时候,
咱们可以统计出来用户是从哪一个地方,什么时间访问网站的。好比腾讯分析网站
统计的时候是靠什么知道用户从什么地方去的网站
在HTTP协议中 头信息中有一个很重要的选项 referer
referer 表示的是网页的来源以及上一页的地址
若是直接在浏览器输入地址,进入网站,则没有referer头信息
因此,服务器可根据referer来知道用户从哪一个网站进来的和图片是从哪一个网站进来的
利用referer头信息来设置防盗链的具体操做步骤以下:
/** 如何配置apache服务器。用于图片防盗链(使用url重写) 在web服务器层面,咱们能够在http协议的referer头信息来判断, 若是来自站外,则统一重写到一个很小的防盗链提醒图片上去 步骤: 1.打开 apache 重写模块 mod_rewrite (D:\wamp\bin\apache\apache2.4.9\conf) #LoadModule rewrite_module modules/mod_rewrite.so 把#去掉,重启apache 2.在须要防盗的网站或者目录下,写 .htaccess 文件(windows下不能直接建立,能够另存) 并指定防盗链规则 分析referer信息,若是不是来自本站,则重写 **/ 重写规则 .htaccess 文件 1.哪一种状况重写规则 是jpeg/gif/png图片的时候 是referer头与localhost不匹配的时候 2.怎么重写 统一 rewrite 到某个防盗链图片上 RewriteEngine On //只是在改页面下生效 Rewrite Base /HTTPxieyi/day1 //会对如下格式的文件进行重写规则 RewriteCond %{REQUEST_FILENAME} .*\.(jpg|jpeg|gif|png) [NC] //若是不是来自localhost的用户,会重写 RewriteCond %{HTTP_REFERER} !localhost [NC] //会重写到自学it网的logo上 RewriteRule .* http://www.zixue.it/static/image/common/zixuelogo.png
html的具体代码以下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>图片的防盗链</title> </head> <body> <p> <img src="http://imgsrc.baidu.com/forum/w%3D580%3B/sign=5547962a02d162d985ee621421e4a8ec/0d338744ebf81a4c06403427df2a6059242da6ea.jpg" alt=""> <img src="./bb.jpg" alt=""> <img src="./aa.jpg" alt=""> </p> </body> </html>
反防盗链的具体代码以下:
<?php /** 反防盗链 ****/ require('./07.class.php'); $http = new Http('http://localhost/HTTPxieyi/day1/bb.jpg'); //若是没有加如下这句话,就会显示盗链 //加上referer就会告诉浏览器,我是来自localhost的,不是来自其余网站的,你不用防我 $http->setHeader('Referer: http://localhost'); $res = $http->get(); //aaa.显示的倒链 //file_put_contents('./aaa.jpg',substr(strstr($res,"\r\n\r\n"),4)); file_put_contents('./bbb.jpg',substr(strstr($res,"\r\n\r\n"),4)); //应该在判断路径或者response的mime头信息,肯定图片的类型