http請求頭

1. document.referrer 與 Request Headers的refere

Request Headers上referer當前頁面的地址欄。

而當前的頁面的上一個頁面 document.referrer,並不一定是當前頁面的url

 

 2.瀏覽器緩存

關於Pragma:no-cache,跟Cache-Control: no-cache相同。

Pragma: no-cache兼容http 1.0 ,Cache-Control: no-cache是http 1.1提供的。

因此,Pragma: no-cache可以應用到http 1.0 和http 1.1,而Cache-Control: no-cache只能應用於http 1.1.

 

瀏覽器緩存主要有兩類:緩存協商和徹底緩存,也有稱之爲協商緩存和強緩存。

1.強緩存:不會向服務器發送請求,直接從緩存中讀取資源,在chrome控制檯的network選項中可以看到該請求返回200的狀態碼;

2.協商緩存:向服務器發送請求,服務器會根據這個請求的request header的一些參數來判斷是否命中協商緩存,如果命中,則返回304狀態碼並帶上新的response header通知瀏覽器從緩存中讀取資源;

兩者的共同點是,都是從客戶端緩存中讀取資源;區別是強緩存不會發請求,協商緩存會發請求。

 

 

強制緩存

 

Expires:response header裏的過期時間,瀏覽器再次加載資源時,如果在這個過期時間內,則命中強緩存。

Cache-Control:當值設爲max-age=300時,則代表在這個請求正確返回時間(瀏覽器也會記錄下來)的5分鐘內再次加載資源,就會命中強緩存。

cache-control除了該字段外,還有下面幾個比較常用的設置值:

-no-cache:不使用本地緩存。需要使用緩存協商,先與服務器確認返回的響應是否被更改,如果之前的響應中存在ETag,那麼請求的時候會與服務端驗證,如果資源未被更改,則可以避免重新下載。

-no-store:直接禁止瀏覽器緩存數據,每次用戶請求該資源,都會向服務器發送一個請求,每次都會下載完整的資源。

-public:可以被所有的用戶緩存,包括終端用戶和CDN等中間代理服務器。

-private:只能被終端用戶的瀏覽器緩存,不允許CDN等中繼緩存服務器對其緩存。

 

 

Cache-Control僅指定了max-age,所以默認爲private,緩存時間爲31536000秒(365天)也就是說,在365天內再次請求這條數據,都會直接獲取緩存數據庫中的數據,直接使用。

 

沒懂的話,我們換通俗一點的話來說一遍。當客戶端第一次訪問資源的時候,服務端在返回資源內容的同時也返回了Expires: Sun, 16 Oct 2016 05:43:02 GMT。

 

服務端告訴瀏覽器: 你Y的先把這個文件給我緩存起來,在這個過期時間之前,這個文件都不會變化了,你下次需要這個文件的時候,你就不要過來找我要了,你就去緩存中拿就好了,又快又好。

 

瀏覽器回答說:諾。

 

於是在第二次html頁面中又要訪問這個資源的時候,並且訪問的日期在Sun, 16 Oct 2016 05:43:02 GMT之前,瀏覽器就不去服務器那邊獲取文件了,自己從緩存中自食其力了。

 

但是呢,瀏覽器畢竟是在客戶端的,客戶端的時間可是不準確的,用戶可以隨着自己的喜好修改自己機器的時間,比如我把我機器的時間調成Sun, 16 Oct 2016 05:43:03 GMT,那麼呢?我的瀏覽器就不會再使用緩存了,而每次都去服務器獲取文件。於是,服務器怒了:給你個絕對時間,你由於環境被修改沒法判斷過期,那麼我就給你相對時間吧。於是就返回了Cache-Control: max-age:600,瀏覽器你給我緩存個10分鐘去。於是瀏覽器只有乖乖的緩存10分鐘了。

 

但是問題又來了,如果有的服務器同時設置了Expires和Cache-Control怎麼辦呢?(不是閒的沒事幹,而是由於Cache-Controll是HTTP1.1中才有的)那麼就是根據更先進的設置Cache-Control來爲標準。

 

好了,現在有個問題,我有個文件可能時不時會更新,服務端非常希望客戶端能時不時過來問一下這個文件是否過期,如果沒有過期,服務端不返回數據給你,只告訴瀏覽器你的緩存還沒有過期(304)。然後瀏覽器使用自己存儲的緩存來做顯示。這個就叫做條件請求。

 

 

 

協商緩存

 

Last-Modify/If-Modify-Since:瀏覽器第一次請求一個資源的時候,服務器返回的header中會加上Last-Modify,Last-modify是一個時間標識該資源的最後修改時間;當瀏覽器再次請求該資源時,request的請求頭中會包含If-Modify-Since,該值爲緩存之前返回的Last-Modify。服務器收到If-Modify-Since後,根據資源的最後修改時間判斷是否命中緩存

Etag:web服務器響應請求時,告訴瀏覽器當前資源在服務器的唯一標識(生成規則由服務器決定)。

If-None-Match:當資源過期時(使用Cache-Control標識的max-age),發現資源具有Etage聲明,則再次向web服務器請求時帶上頭If-None-Match (Etag的值)。web服務器收到請求後發現有頭If-None-Match 則與被請求資源的相應校驗串進行比對,決定是否命中協商緩存;

ETagLast-Modified的作用和用法,他們的區別:

1.Etag要優於Last-Modified。Last-Modified的時間單位是秒,如果某個文件在1秒內改變了多次,那麼他們的Last-Modified其實並沒有體現出來修改,但是Etag每次都會改變確保了精度;

2.在性能上,Etag要遜於Last-Modified,畢竟Last-Modified只需要記錄時間,而Etag需要服務器通過算法來計算出一個hash值;

3.在優先級上,服務器校驗優先考慮Etag。

 

瀏覽器緩存過程

1.瀏覽器第一次加載資源,服務器返回200,瀏覽器將資源文件從服務器上請求下載下來,並把response header及該請求的返回時間一併緩存;

2.下一次加載資源時,先比較當前時間和上一次返回200時的時間差,如果沒有超過cache-control設置的max-age,則沒有過期,命中強緩存,不發請求直接從本地緩存讀取該文件(如果瀏覽器不支持HTTP1.1,則用expires判斷是否過期);如果時間過期,則向服務器發送header帶有If-None-Match和If-Modified-Since的請求

3.服務器收到請求後,優先根據Etag的值判斷被請求的文件有沒有做修改,Etag值一致則沒有修改,命中協商緩存,返回304;如果不一致則有改動,直接返回新的資源文件帶上新的Etag值並返回200;;

4.如果服務器收到的請求沒有Etag值,則將If-Modified-Since和被請求文件的最後修改時間做比對,一致則命中協商緩存,返回304;不一致則返回新的last-modified和文件並返回200;

 

 

瀏覽器中寫地址,回車 

F5 

Ctrl+F5

假設對一個資源:

 

瀏覽器第一次訪問,獲取資源內容和cache-control: max-age:600,Last_Modify: Wed, 10 Aug 2013 15:32:18 GMT於是瀏覽器把資源文件放到緩存中,並且決定下次使用的時候直接去緩存中取了。

 

瀏覽器url回車

瀏覽器發現緩存中有這個文件了,好了,就不發送任何請求了,直接去緩存中獲取展現。(最快)

 

下面我按下了F5刷新

F5就是告訴瀏覽器,別偷懶,好歹去服務器看看這個文件是否有過期了。於是瀏覽器就膽膽襟襟的發送一個請求帶上If-Modify-since:Wed, 10 Aug 2013 15:32:18 GMT

 

然後服務器發現:誒,這個文件我在這個時間後還沒修改過,不需要給你任何信息了,返回304就行了。於是瀏覽器獲取到304後就去緩存中歡歡喜喜獲取資源了。

 

按下了Ctrl+F5

這個可是要命了,告訴瀏覽器,你先把你緩存中的這個文件給我刪了,然後再去服務器請求個完整的資源文件下來。於是客戶端就完成了強行更新的操作...

 

 

 參考自:

https://www.aliyun.com/jiaocheng/980241.html?spm=5176.100033.2.22.69fb11ea0MUI4K

https://www.aliyun.com/jiaocheng/980412.html?spm=5176.100033.2.23.69fb11eaDVwhXr

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章