HTTP請求的快取(Cache)機制

小時刻發表於2019-05-24

原文地址:http://small.aiweimeng.top/index.php/archives/58.html

先來一張圖:

 

####下面簡單的來描述一下HTTP Cache機制

當資源資源第一次被訪問的時候,http status返回200,在頭部攜帶當前資源的描述資訊,eg:

最後修改的時間:```Last-Modified```
資源狀態唯一標識:```Etag```
資源在客戶端快取的過期時間:```Expires```


同時瀏覽器會將資源快取到cache目錄,並儲存檔案描述資訊。

當客戶端第二次請求資源時,會先檢查cache目錄中是否含有該資源,如果有,並且還沒到Expires設定的時間,
即檔案還沒有過期,那麼此時客戶端將直接從Cache目錄中讀取檔案,而不再傳送請求

如果資源已經過期,客戶端會傳送一次http請求到伺服器,同時在header攜帶上次修改的時間:
```text
If-Modified-Since Thu, 26 Nov 2009 13:50:19 GMT
If-None-Match "8fb8b-14-4794674acdcc0"
```

####為什麼會返回上一次的資訊呢?

web伺服器在接收到請求時,會先解析header裡面的資訊,然後校驗頭部資訊。
如果該資原始檔從上次時間到現在都沒有修改或者Etag資訊沒有變化,,則web伺服器將會直接返回304狀態,
從而不會在資原始檔,狀態頭部資訊如下:
```text
(Status-Line) HTTP/1.1 304 Not Modified
Date Thu, 26 Nov 200914:09:07 GMT
Server Apache/2.2.11 (Unix)PHP/5.2.9
Connection Keep-Alive
Keep-Alive timeout=5, max=100
Etag "8fb8b-14-4794674acdcc0"
```

這樣,就能夠很大程度上減少網路頻寬以及提升使用者的瀏覽器體驗。
當然,如果伺服器經過匹配發現檔案修改過了,就會將檔案資源返回,並帶上新檔案狀態資訊。


####基本欄位

```Expires:```
檔案在本地快取的過期時間,如果客戶端發現快取中的檔案沒有過期,則不傳送請求


```Cache-Control:```
Cache-Control指定請求和響應遵循的快取機制。
在請求訊息或響應訊息中設定Cache-Control並不會修改另一個訊息處理過程中的快取處理過程。

請求時的快取指令包括
```text
no-cache
no-store
max-age
max-stale
min-fresh
only-if-cached
```
響應訊息中的指令包括
```text
public
private
no-cache
no- store
no-transform
must-revalidate
proxy-revalidate
max-age
```

####指令含義:

```public:```

響應可被任何快取區快取。

```Private:```

對於單個使用者的整個或部分響應訊息,不能被共享快取處理。
這允許伺服器僅僅描述當使用者的部分響應訊息,此響應訊息對於其他使用者的請求無效。   

```no-cache:```

請求或響應訊息不能快取。

```no-store:```

用於防止重要的資訊被無意的釋出。
在請求訊息中傳送將使得請求和響應訊息都不使用快取。

```max-age:```

客戶端可以接收生存期不大於指定時間(以秒為單位)的響應。  

```min-fresh:```

客戶機可以接收響應時間小於當前時間加上指定時間的響應。   

```max-stale:```

客戶端可以接收超出超時期間的響應訊息。
如果指定max-stale訊息的值,那麼客戶端可以接收超出超時期指定值之內的響應訊息。

 


####```Etag/If-None-Match``` 

一對驗證檔案實體的標記 "Entity Tag:的響應/請求頭.
Apache中,ETag的值,預設是對檔案的索引節(INode),大小(Size)和最後修改時間(MTime)進行Hash後得到的

```Last-Modified/If-Modified-Since:```

一對驗證檔案的修改時間的響應/請求頭

Expires、 Cache-Control、Last-Modified、ETag是RFC2616(HTTP/1.1)協議中和網頁快取相關的幾個欄位。 前兩個用來控制快取的失效日期,瀏覽器可通過它來判定,需不需要發出HTTP請求; 後兩個用來驗證網頁的有效性,伺服器端利用它來驗證這個檔案是否需要重新返回Last-Modified VS Etag

既然有了Last-Modified,為什麼還要用ETag欄位呢?因為如果在一秒鐘之內對一個檔案進行兩次更改,Last-Modified就會不正確。因此,HTTP/1.1利用Entity Tag頭提供了更加嚴格的驗證。

相關文章