今天一早開啟微信,就看到國產github——gitee崩了。
Issue列表裡面全是反饋圖片顯示異常,仔細一看,原來是圖床的防盜鏈。
場景復現
之前沒用過gitee,火速去建了一個賬號試驗一下。
我在我的gitee中上傳一張圖片,在gitee本站裡面顯示是正常的。
右鍵複製這張圖片的地址,放到一個第三方的線上編輯器中,發現圖片變成gitee的logo了
什麼是防盜鏈
防盜鏈不是防止一根鏈條,正確的停頓應該是防·盜鏈——防止其他網站盜用我的連結。
我把圖片上傳到gitee的伺服器,得到了圖片的連結,然後拿著這個連結在第三方編輯器中使用,這就是在“盜用”——因為這張圖片佔用了gitee的伺服器資源,卻為第三方編輯器工作,gitee得不到好處,還得多花錢。
如何實現防盜鏈
要實現防盜鏈,就需要知道圖片的請求是從哪裡發出的。可以實現這一功能的有請求頭中的origin
和referer
。origin
只有在XHR請求中才會帶上,所以圖片資源只能藉助referer
。其實gitee也確實是這麼做的。
通過判斷請求的referer,如果請求來源不是本站就返回302,重定向到gitee的logo上,最後在第三方網站引用存在gitee的資源就全變成它的logo了。
可以在開發者工具中看到第三方網站請求gitee圖片的流程:
- 首先請求正常的圖片,但是沒有返回200,而是302重定向,其中響應頭中的location就是要重定向去向的地址;
- 接著瀏覽器會自動請求這個location,並用這個返回結果代替第一次請求的返回內容;
最後,我們的圖片在第三方網站就變成gitee的logo了。
如何破解防盜鏈
想讓gitee不知道我在盜用,就不能讓他發現請求的來源是第三方,只要把referer藏起來就好,可以在終端嘗試這段程式碼:
curl 'https://images.gitee.com/uploads/images/2022/0326/155444_dc9923a4_10659337.jpeg' \
-o noReferer.jpg
這段?程式碼的意思是請求這張jpg圖片資源,把返回結果以noReferer.jpg
這個名稱儲存在當前目錄下,並且沒有帶上referer,測試結果是圖片正常儲存下來了。
就像加上了gitee本站的referer一樣可以正常請求?:
curl 'https://images.gitee.com/uploads/images/2022/0326/155444_dc9923a4_10659337.jpeg' \
-H 'referer: https://gitee.com' \
-o fromGitee.jpg
而在第三方網站請求的效果就像這段?程式碼
curl 'https://images.gitee.com/uploads/images/2022/0326/155444_dc9923a4_10659337.jpeg' \
-H 'referer: https://editor.mdnice.com/' \
-o otherReferer.png
帶上了第三方網站的標識https://editor.mdnice.com
最終無法正常下載。
gitee做的不夠完善嗎
測試完上面的三段程式碼,不知道你會不會疑惑,gitee為什麼不把“請求來源不能是第三方網站”的策略改成“請求來源必須是本站點”呢?換句話說,控制referer不能為空,只要是空就重定向。
因為在瀏覽器的位址列中直接輸入這個圖片的url,然後回車,發起的請求是沒有referer欄位的,在這種場景下如果還是返回gitee的logo,就顯得不太合理了。
圖片的url:https://images.gitee.com/uplo...
圖片看不到了,現在怎麼辦
如果你的個人搭建的部落格裡面用了很多存在gitee的圖片,你可以在html的head部分加上這樣一行
<meta name="referrer" content="no-referrer" />
或者
<img referrer="no-referrer|origin|unsafe-url" src="{item.src}"/>
來阻止請求因帶上站點來源而被重定向成gitee的logo。
如果你是部落格的訪問者,可以藉助一個chrome小外掛ModHeader,把referer給“擦掉”
這樣第三方站點就可以正常訪問啦~
結語
上面提到的解決方式只是開個玩笑,臨時恢復使用可以。但還是要慢慢把圖片遷移到自己的伺服器才最可靠。
如果覺得這篇文章對你有幫助,給我點個讚唄~這對我很重要
點個在看更好!