網頁中經常需要顯示圖片給用戶看,對網站本身來說有的圖片是從本地圖片伺服器來的,但是一旦數量多了以後,磁碟空間又是一個問題。 所以有時就希望顯示其他網站的Image,直接把其他網站的圖片顯示在我的網站上。但並不是所有的外網Image 都能直接連接過來顯示。 很多情況下網站開發人員就會遇到 403 fo ...
網頁中經常需要顯示圖片給用戶看,對網站本身來說有的圖片是從本地圖片伺服器來的,但是一旦數量多了以後,磁碟空間又是一個問題。
所以有時就希望顯示其他網站的Image,直接把其他網站的圖片顯示在我的網站上。但並不是所有的外網Image 都能直接連接過來顯示。
很多情況下網站開發人員就會遇到 403 forbidden的問題。比如想顯示來自IMDB的一張圖片
<img src="http://ia.media-imdb.com/images/M/MV5BMjIwMjYyNjk4Nl5BMl5BanBnXkFtZTcwNzA4NDYwMw@@._V1_UY317_CR12,0,214,317_AL_.jpg" height="350" width="200">
本地localhost Debug的時候完全可以顯示,但是將網站部署到伺服器後就會遇到這樣的錯誤
奇怪的是通過瀏覽器訪問圖片的連接,圖片就正常的顯示了出來。
這又是為什麼?
其實這就是HotLinking 盜鏈問題, 可以通過配置網站Server 端來實現這種反盜鏈的行為。
為什麼像IMDB這樣的網站要做 Anti HotLinking反盜鏈的事情呢?
版權的問題是一方面。
另一方面可以稱作Bandwidth Theft, 當用戶訪問IMDB頁面的時候,IMDB需要Bandwidth傳輸數據,而Bandwidth 是網站的成本之一。
好比誰也不願意陌生人偷偷的把電器插到你的插座,偷偷的用你的電,而你去負擔所有的費用。
如何配置Server實現Anti HotLinking 呢?
以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劫持HttpRequest 修改UrlReferer實現的。
對網站開發人員有什麼解決辦法嗎?
將外網的Image下載 再轉換成 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的字元串 />
歡迎訪問我的個人主頁 51zhang.net 網站還在不斷開發中…..