1. 程式人生 > >圖片防盜鏈的解決辦法

圖片防盜鏈的解決辦法

在做圖片展示部分的時候發現img標籤src為圖片url時無法顯示,發現是這些圖片來源網站為了防止圖片盜鏈浪費資源所以不讓外站訪問。它們的識別機制是根據http請求裡的header中的referer來判斷來源網站,比如我在chrome開發者工具裡檢視值值值網站的圖片,就能看到完整的request header。

  1. Accept:   image/webp,*/*;q=0.8
  2. Accept-Encoding:   gzip,deflate,sdch
  3. Accept-Language:   zh-CN,zh;q=0.8
  4. Cache-Control:   max-age=0
  5. Connection:   keep-alive
  6. Host:   img.zhizhizhi.net
  7. If-Modified-Since:   Sat, 16 Aug 2014 06:26:23 GMT
  8. If-None-Match:   "74bbe01bb9cf1:0"
  9. Referer:   http://www.zhizhizhi.com/
  10. User-Agent:   Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36

其中的referer就是值值值網站的url。那我要怎麼解決使用者可以從我的網站上檢視其他網站的圖片這個問題呢?

我首先想到的解決方案是通過js偽造referer,不過查閱資料後發現就算你請求圖片時改了referer,瀏覽器也會包裝你的請求,把referer修改成localhost:8080,所以這個辦法是行不通的。

還有一種流傳的很廣的方案,就是把圖片放在一個iframe標籤裡進行訪問,這樣就相當於在瀏覽器中憑空開了一個標籤頁,這樣的請求的referer是空的,一般網站的防盜鏈方案都是允許referer為空的資源請求。

那麼可以根據上述思路來解決這個問題,把圖片放在一個ifame標籤裡,然後再改變img的src進行請求,最後再在保留img的前提下去掉iframe標籤。(這是最初想法,可是最後的解決方案不是這樣,也就沒有實踐iframe到底可不可以去除,還需要實踐去證明)

這時我發現了一個lazyload的jquery外掛,可以延遲載入圖片,剛好在我的網站中可以應用。檢視它的原始碼發現它的實現機理是先給img標籤設定src為未載入的一張預設圖片,同時設定一個data-original屬性為圖片的真實url,在瀏覽器視窗掃描到圖片時對圖片進行載入。

我的設想是可以在頁面中增加一個display:none的iframe,然後要載入圖片時就往iframe中新增img標籤,這樣圖片http請求的referer就是空的,就能正確下載圖片。然後把可視頁面中的img的src屬性設定為正確url,因為圖片已經下載好,就可以從快取中讀取圖片。

採取這種解決方案後,三個網站的外鏈圖片都恩呢更正確顯示,可視虎撲的外鏈圖片還是不能載入。

我參考了 https://stackoverflow.com/questions/3877027/jquery-callback-on-image-load-even-when-the-image-is-cached/3877079#3877079?newreg=a7cd36a6037243a8a0e4523783c91ae9 ,採取了下面的方法,雖然還是不知道為什麼,問題還是解決了。希望以後能探究清楚。

$("img").one("load",function(){// do stuff}).each(function(){if(this.complete) $(this).load();})