网页中常常须要显示图片给用户看,对网站自己来讲有的图片是从本地图片服务器来的,可是一旦数量多了之后,磁盘空间又是一个问题。git
因此有时就但愿显示其余网站的Image,直接把其余网站的图片显示在个人网站上。但并非全部的外网Image 都能直接链接过来显示。web
不少状况下网站开发人员就会遇到 403 forbidden的问题。好比想显示来自IMDB的一张图片chrome
<img src="http://ia.media-imdb.com/images/M/MV5BMjIwMjYyNjk4Nl5BMl5BanBnXkFtZTcwNzA4NDYwMw@@._V1_UY317_CR12,0,214,317_AL_.jpg" height="350" width="200">
本地localhost Debug的时候彻底能够显示,可是将网站部署到服务器后就会遇到这样的错误跨域
奇怪的是经过浏览器访问图片的链接,图片就正常的显示了出来。浏览器
这又是为何?其实Referer是由浏览器自动加上的,可是也有例外好比服务器
1. 直接经过浏览器访问函数
2. 在web前段使用location.href 或者location.replace网站
3. 利用HTTPS等加密协议google
这就是HotLinking 盗链问题, 能够经过配置网站Server 端来实现这种反盗链的行为。加密
版权的问题是一方面。
另外一方面能够称做Bandwidth Theft, 当用户访问IMDB页面的时候,IMDB须要Bandwidth传输数据,而Bandwidth 是网站的成本之一。
比如谁也不肯意陌生人偷偷的把电器插到你的插座,偷偷的用你的电,而你去负担全部的费用。
以Asp.net MVC 为例
能够给Controller 添加ActionFilter 或者添加处理AntiHotLinking 的 IHttpHandler
核心都是UrlReferrer
HttpRequest 有个字段 UrlReferrer:
该字段表示哪一个Url 经过像上面Img Src的方式访问了Server.
//访问者的域 var refDomain = Request.UrlReferrer.Host; //当前WebSite的域 var serverDomain = Request.Url.Host;
最后能够经过判断 是否来自同一个域 来决定Anti HotLinking的策略
或者能够经过在web.config 中配置URLRewrite来实现
<rewrite> <rules> <rule name="Anti HotLinking Rule for Image" enabled="true" stopProcessing="true"> <match url=".*\.(gif|jpg|png)$" /> <conditions> <add input="{HTTP_REFERER}" negate="true" pattern="^$" /> <add input="{HTTP_REFERER}" negate="true" pattern="http://www.yourwebsite.com/.*" /> <add input="{HTTP_REFERER}" negate="true" pattern="http://yourwebsite.com/.*" /> </conditions> <action type="Rewrite" url="/images/anti-hotlinking.png" /> </rule> </rules> </rewrite>
这里给你们推荐一个Chrome 插件 Anti-Anti-HotLinking
安装后就能看到未能显示的图片。
对该插件我没有仔细研究,有多是经过Download来解决Hotlinking 问题的,也有多是经过Chrome劫持Request 修改UrlReferer实现的。
1. 将外网的Image在Server端下载 再转换成 base64 最后传输给img 标签。
public static string ImageToBase64(Stream imageStream, ImageFormat format) { using (System.Drawing.Image image = System.Drawing.Image.FromStream(imageStream)) { using (MemoryStream stream = new MemoryStream()) { image.Save(stream, format); var result = System.Convert.ToBase64String(stream.ToArray()); return result; } } }
<img src="data:image/png;base64,这里存放转换成base64的字符串 />
2. 利用RefererKiller这个JavaScript插件 绕过UrlReferer
ReferrerKiller.imageHtml("fakeweb/fakeimage.png"); 返回可以显示的img的Html字符串
ReferrerKiller.imageHtml("fakeweb/fakeimage.png"); 返回可以显示的img的DOM节点
其实这两个函数是同一个东西,能够捡方便的用。
这种方式解决HotLinking问题其实原理很简单,在web中 好比<script src="differentDomain/fake.js"> </script>
加载js 是没有跨域访问的问题。
ReferrerKiller 就动态生成一个iframe,并在iframe内加入img标签。利用src加载的特性把代码放到src中,就能够去掉Referer。
因此ReferrerKiller.imageHtml返回的是一个能显示图片的iframe。
欢迎访问个人我的主页 51zhang.net 网站还在不断开发中…..