跨域訪問和防盜鏈基本原理(一)

發表於2015-10-18

一、什麼是防盜鏈

網站資源都有域的概念,瀏覽器載入一個站點時,首先載入這個站點的首頁,一般是index.html或者index.php等。頁面載入,如果僅僅是載入一個index.html頁面,那麼該頁面裡面只有文字,最終瀏覽器只能呈現一個文字頁面。豐富的多媒體資訊無法在站點上面展現。

那麼我們看到的各類元素豐富的網頁是如何在瀏覽器端生成並呈現的?其實,index.html在被解析時,瀏覽器會識別頁面原始碼中的img,script等標籤,標籤內部一般會有src屬性,src屬性一般是一個絕對的URL地址或者相對本域的地址。瀏覽器會識別各種情況,並最終得到該資源的唯一地址,載入該資源。具體的載入過程就是對該資源的URL發起一個獲取資料的請求,也就是GET請求。各種豐富的資源組成整個頁面,瀏覽器按照html語法指定的格式排列獲取到各類資源,最終呈現一個完整的頁面。因此一個網頁是由很多次請求,獲取眾多資源形成的,整個瀏覽器在一次網頁呈現中會有很多次GET請求獲取各個標籤下的src資源。

上圖是一篇本站的部落格網頁呈現過程中的抓包截圖。可以看到,大量的載入css、js和圖片類資源的get請求。

觀察其中的請求目的地址,可以發現有兩類,一個是本站的43.242段的IP地址,這是本站的空間地址,即向本站自身請求資源,一般來說這個是必須的,訪問資源由自身託管。另外一類是訪問182的網段拉取資料。這類資料不是託管站內的,是在其他站點的。瀏覽器在頁面呈現的過程,拉取非本站的資源,這就稱“盜鏈”。

準確的說,只有某些時候,這種跨站訪問資源,才被稱為盜鏈。假設B站點作為一個商業網站,有很多自主版權的圖片,自身展示用於商業目的。而A站點,希望在自己的網站上面也展示這些圖片,直接使用:

這樣,大量的客戶端在訪問A站點時,實際上消耗了B站點的流量,而A站點卻從中達成商業目的。從而不勞而獲。這樣的A站點著實令B站點不快的。如何禁止此類問題呢?

HTTP協議和標準的瀏覽器對於解決這個問題提供便利,瀏覽器在載入非本站的資源時,會增加一個頭域,頭域名字固定為:

而在直接貼上地址到瀏覽器位址列訪問時,請求的是本站的該url的頁面,是不會有這個referer這個http頭域的。使用Chrome瀏覽器的除錯臺,開啟network標籤可以看到每一個資源的載入過程,下面兩個圖分別是主頁面和一個頁面內資源的載入請求截圖:

這個referer標籤正是為了告訴請求響應者(被拉取資源的服務端),本次請求的引用頁是誰,資源提供端可以分析這個引用者是否“友好”,是否允許其“引用”,對於不允許訪問的引用者,可以不提供圖片,這樣訪問者在頁面上就只能看到一個圖片無法載入的瀏覽器預設佔位的警告圖片,甚至服務端可以返回一個預設的提醒勿盜鏈的提示圖片。

一般的站點或者靜態資源託管站點都提供防盜鏈的設定,也就是讓服務端識別指定的Referer,在服務端接收到請求時,通過匹配referer頭域與配置,對於指定放行,對於其他referer視為盜鏈。

相關文章