如何使用防盜鏈圖片
背景
最近自己寫了一個網站玩,在引用別人網站的圖片是遇到了一些小問題。
<img src="https://xxxx" alt="">
像這個樣子,src後面跟的是別的網站的圖片的url。
問題
有的圖片在我們釋出的網站上能正常加載出來,有的一些就載入不出來,審查一下元素,會看到Failed to load resource: the server responded with a status of 403 ()
的報錯。
發現和解決問題
經過了解,發現這是一個叫做防盜鏈的東西,網站設定了防盜鏈的策略,會在後臺判斷請求的Referrer屬性是不是來自於一個非本域名的網站,如果來源不是本域名就返回403 forbidden
。我們要做的就是用最方便的方法使得我的頁面能夠不受他的防盜鏈策略的影響。我從網上搜到了幾個解決方法。
圖片預下載
這個是最直觀的解決方式了,正在使用別人的圖,先把圖片下載下來,儲存到自己的伺服器上,然後就等於是用自己的了~ 如果自己沒有伺服器,可以去網上找找圖床,應該也能解決問題。
刪除Header中的Referrer
保證最佳效果的最簡單的寫法就是在html檔案的head中新增一個meta標籤<meta name="referrer" content="never" />
為什麼叫保證效果的最簡單寫法 ?下面看一些資料對比。
刪除Header中的Referrer的方法也有多種:新增meta標籤
和新增ReferrerPolicy屬性
新增meta標籤
一種方法是給頁面新增一個meta標籤,在meta標籤裡指定referrer的值,比如<meta name="referrer" content="xxx" />。網上可以查到各種奇奇怪怪的值,其實我總結了來源於兩個地方。
一個是來自whatwg
的標準。他給meta標籤的referrer屬性定義了四個值:never
,always
,origin
,default
。如果需要關閉referrer,就將referrer的值設定成”never”。這個標準還是比較老的,而且在他的主頁上也明確寫了”This document is obsolete(廢棄的).”。不過據我調研,或許正是由於這個標準比較老,反而導致絕大多數瀏覽器對他的支援都很好,因禍得福蛤蛤。
另外一個是來自MDN的標準。他給meta標籤的referrer屬性定義了五個值,如果要關閉referrer,就將它的值設定成no-referrer
。
不過我們需要注意的是,meta標籤新增的位置也很重要,有的瀏覽器能夠識別非head標籤中的meta標籤,有的就不行。在實際使用的時候還要小心,這一點下文會有一個更具體的比較。
新增ReferrerPolicy屬性
新增meta標籤相當於對文件中的所有連結都取消了referrer,而ReferrerPolicy則更精確的指定了某一個資源的referrer策略。關於這個策略的定義可以參照MDN。比如我想只對某一個圖片取消referrer,如下編寫即可:
<img src="xxxx.jpg"referrerPolicy="no-referrer" />
nothing | meta in head referrer=never | meta in head referrer=no-referrer | meta referrer=never | meta referrer=no-referrer | img referrerPolicy=no-referrer | |
---|---|---|---|---|---|---|
Chrome | N | Y | Y | Y | Y | Y |
Firefox | N | Y | Y | N | N | Y |
Edge/IE | N | Y | N | Y | N | N |
可以看出Chrome瀏覽器對各種寫法都支援的最好。Firefox支援所有標準的寫法,但是不支援沒有寫在head標籤中的meta標籤;Edge/IE則不支援MDN裡定義的”no-referrer”配置項,果然是個古董。。。
總的來說,保證最佳效果的最簡單的寫法就是新增一個meta標籤<meta name="referrer" content="never" />,這樣就不用考慮瀏覽器的差別了,雖然這種寫法並不被官方推薦(主要還是要遷就IE這個古董,放棄了理論上更為正確的標準)。
使用iframe
這個圖片就是使用了防盜鏈的http://json.image.alimmdn.com/vsou.png
- 建一個空的iframe
- iframe設定src,內容就是圖片或一段html
var body = document.querySelector("body"); var iframe = document.createElement("iframe"); var html = '<img src="http://json.image.alimmdn.com/vsou.png"/>'; iframe.src = 'javascript:void(function(){document.open();document.write(\'' + html + '\');document.close();}())'; body.appendChild(iframe);
略微設定一下樣式
iframe.style.position="fixed"; iframe.style.width="100%"; iframe.style.height="100%"; iframe.style.border=0; iframe.style.zIndex=10; iframe.style.top=0; iframe.style.left=0;
上面一段程式碼有一個關鍵因素,就是在iframe之外,不能有任何其他圖片該域名(示例圖片所在域名)下的圖片,否則功虧一簣
上面的解釋是從網上搜到的,沒有什麼問題,總結起來方法就是我們建立一個iframe,然後把我們要顯示的帶有防盜鏈圖片連結的html標籤,以字元換的形式傳給iframe的src屬性就行了。
不過這個方法是有問題的,因為iframe設定width和height都無效,所以用在我的網站上樣式是不合適的。具體為什麼這樣,大家可以查一下iframe,具體的瞭解一下。