關於img 403 forbidden的一些思考

網頁中常常須要顯示圖片給用戶看,對網站自己來講有的圖片是從本地圖片服務器來的,可是一旦數量多了之後,磁盤空間又是一個問題。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的時候徹底能夠顯示,可是將網站部署到服務器後就會遇到這樣的錯誤跨域

image

奇怪的是經過瀏覽器訪問圖片的鏈接,圖片就正常的顯示了出來。瀏覽器

這又是爲何?其實Referer是由瀏覽器自動加上的,可是也有例外好比服務器

1. 直接經過瀏覽器訪問函數

2. 在web前段使用location.href 或者location.replace網站

3. 利用HTTPS等加密協議google

這就是HotLinking 盜鏈問題, 能夠經過配置網站Server 端來實現這種反盜鏈的行爲。加密

 

爲何像IMDB這樣的網站要作 Anti HotLinking反盜鏈的事情呢?

版權的問題是一方面。

另外一方面能夠稱做Bandwidth Theft, 當用戶訪問IMDB頁面的時候,IMDB須要Bandwidth傳輸數據,而Bandwidth 是網站的成本之一。

比如誰也不肯意陌生人偷偷的把電器插到你的插座,偷偷的用你的電,而你去負擔全部的費用。

 

如何配置Server實現Anti HotLinking 呢?

以Asp.net MVC 爲例

能夠給Controller 添加ActionFilter 或者添加處理AntiHotLinking 的 IHttpHandler

核心都是UrlReferrer

HttpRequest 有個字段 UrlReferrer:

image

 

該字段表示哪一個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  網站還在不斷開發中…..

相關文章
相關標籤/搜索