網頁中常常須要顯示圖片給用戶看,對網站自己來講有的圖片是從本地圖片服務器來的,可是一旦數量多了之後,磁盤空間又是一個問題。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 網站還在不斷開發中…..