背景
最近自己寫了一個網(wǎng)站玩就轧,在引用別人網(wǎng)站的圖片是遇到了一些小問題豌鹤。
<img src="https://xxxx" alt="">
像這個樣子,src后面跟的是別的網(wǎng)站的圖片的url叫倍。
問題
有的圖片在我們發(fā)布的網(wǎng)站上能正常加載出來,有的一些就加載不出來豺瘤,審查一下元素吆倦,會看到Failed to load resource: the server responded with a status of 403 ()
的報錯。
發(fā)現(xiàn)和解決問題
經(jīng)過了解坐求,發(fā)現(xiàn)這是一個叫做防盜鏈的東西蚕泽,網(wǎng)站設(shè)置了防盜鏈的策略,會在后臺判斷請求的Referrer屬性是不是來自于一個非本域名的網(wǎng)站桥嗤,如果來源不是本域名就返回403 forbidden
须妻。我們要做的就是用最方便的方法使得我的頁面能夠不受他的防盜鏈策略的影響。我從網(wǎng)上搜到了幾個解決方法泛领。
圖片預下載
這個是最直觀的解決方式了荒吏,正在使用別人的圖,先把圖片下載下來渊鞋,保存到自己的服務(wù)器上绰更,然后就等于是用自己的了~ 如果自己沒有服務(wù)器,可以去網(wǎng)上找找圖床锡宋,應該也能解決問題儡湾。
刪除Header中的Referrer
保證最佳效果的最簡單的寫法就是在html文件的head中添加一個meta標簽<meta name="referrer" content="never" />
為什么叫保證效果的最簡單寫法 ?下面看一些數(shù)據(jù)對比执俩。
刪除Header中的Referrer的方法也有多種:添加meta標簽
和添加ReferrerPolicy屬性
添加meta標簽
一種方法是給頁面添加一個meta標簽盒粮,在meta標簽里指定referrer的值,比如<meta name="referrer" content="xxx" />奠滑。網(wǎng)上可以查到各種奇奇怪怪的值丹皱,其實我總結(jié)了來源于兩個地方。
一個是來自whatwg
的標準宋税。他給meta標簽的referrer屬性定義了四個值:never
,always
,origin
,default
摊崭。如果需要關(guān)閉referrer,就將referrer的值設(shè)置成”never”杰赛。這個標準還是比較老的呢簸,而且在他的主頁上也明確寫了”This document is obsolete(廢棄的).”。不過據(jù)我調(diào)研,或許正是由于這個標準比較老根时,反而導致絕大多數(shù)瀏覽器對他的支持都很好瘦赫,因禍得福蛤蛤。
另外一個是來自MDN的標準蛤迎。他給meta標簽的referrer屬性定義了五個值确虱,如果要關(guān)閉referrer,就將它的值設(shè)置成no-referrer
替裆。
不過我們需要注意的是校辩,meta標簽添加的位置也很重要,有的瀏覽器能夠識別非head標簽中的meta標簽辆童,有的就不行宜咒。在實際使用的時候還要小心,這一點下文會有一個更具體的比較把鉴。
添加ReferrerPolicy屬性
添加meta標簽相當于對文檔中的所有鏈接都取消了referrer故黑,而ReferrerPolicy則更精確的指定了某一個資源的referrer策略。關(guān)于這個策略的定義可以參照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設(shè)置src,內(nèi)容就是圖片或一段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);
略微設(shè)置一下樣式
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;
上面一段代碼有一個關(guān)鍵因素计螺,就是在iframe之外夯尽,不能有任何其他圖片該域名(示例圖片所在域名)下的圖片,否則功虧一簣
上面的解釋是從網(wǎng)上搜到的登馒,沒有什么問題匙握,總結(jié)起來方法就是我們創(chuàng)建一個iframe,然后把我們要顯示的帶有防盜鏈圖片鏈接的html標簽陈轿,以字符換的形式傳給iframe的src屬性就行了圈纺。
不過這個方法是有問題的秦忿,因為iframe設(shè)置width和height都無效,所以用在我的網(wǎng)站上樣式是不合適的蛾娶。具體為什么這樣灯谣,大家可以查一下iframe,具體的了解一下蛔琅。
參考
https://juejin.im/entry/5adaa72c6fb9a07aa43bc665
https://segmentfault.com/a/1190000004968720