瀏覽器通過(guò)HTTP頭部的字段來(lái)控制文件的緩存:要不要緩存以及緩存的過(guò)期時(shí)間。
Cache-Control/Expires
Cache-Control和Expires控制文件的緩存既穆,在緩存文件的有效時(shí)間內(nèi)挽绩,瀏覽器直接使用本地文件灰殴,不與服務(wù)器交互涩搓。
Cache-Control的值是一個(gè)單位為秒的數(shù)字蛙紫,表示緩存文件的有效時(shí)間有多少秒拇派。
Expire的值是一個(gè)絕對(duì)時(shí)間點(diǎn)荷辕,表示緩存文件在某個(gè)時(shí)間點(diǎn)之前有效凿跳。
在Cache-Control和Expires同時(shí)存在的情況下,Cache-Control的優(yōu)先級(jí)高于Expires疮方。
下面舉例說(shuō)明:
- Cache-Control: max-age=600
緩存文件的有效時(shí)長(zhǎng)為600秒控嗜。在接下來(lái)600s內(nèi),如果有請(qǐng)求這個(gè)資源的骡显,瀏覽器不會(huì)發(fā)出請(qǐng)求疆栏,而是直接使用本地緩存的文件。
- Cache-Control: private
告訴瀏覽器不要緩存這個(gè)文件惫谤。
- Expires: Mon, 24 Nov 2025 02:32:46 GMT
緩存文件在2025-11-24 02:32:46 GMT之前有效壁顶。
- Expire: -1
告訴瀏覽器不要緩存這個(gè)文件。
Last-Modified/Etag
Last-Modified的值是一個(gè)絕對(duì)時(shí)間點(diǎn)溜歪,表示文件最近一次修改的時(shí)間若专。
Etag的值是一個(gè)文件的hash。
與上面的Cache-Control和Expire不同蝴猪,如果只使用Last-Modified/Etag對(duì)文件的緩存進(jìn)行控制调衰。那每次訪問(wèn)文件的時(shí)候,瀏覽器會(huì)向服務(wù)器發(fā)起304請(qǐng)求自阱,如果文件沒(méi)有被修改嚎莉,則使用本地文件,否則從服務(wù)器獲取文件沛豌。
當(dāng)Last-Modify或者Etag兩者有一個(gè)和服務(wù)器上的文件相同時(shí)趋箩,則瀏覽器認(rèn)為文件沒(méi)有更新,直接使用本地緩存文件加派。
例子:
- Last-Modified: Thu, 21 Apr 2016 03:17:22 GMT
緩存文件的上次更新的時(shí)間是2016-04-21 03:17:22 GMT阁簸。
- ETag: "27b7-5256d6aeaf7c0"
緩存文件的哈希值是27b7-5256d6aeaf7c0。
強(qiáng)制刷新
- F5
強(qiáng)制使Cache-Control/Expires失效:Cache-Control: max-age=0
此時(shí)哼丈,如果文件還使用了Last-Modified/Etag進(jìn)行緩存控制启妹,則向服務(wù)器發(fā)起304請(qǐng)求。
- Ctrl+F5
強(qiáng)制使上面兩種瀏覽器緩存失效:
Cache-Control:no-cache
Pragma:no-cache
利用瀏覽器緩存
理想的緩存機(jī)制應(yīng)該是這樣的:
- 緩存文件沒(méi)更新醉旦,盡可能使用緩存饶米,不用和服務(wù)器交互;
- 當(dāng)用戶刷新時(shí),盡可能減少瀏覽器和服務(wù)器之間的數(shù)據(jù)傳輸;
- 緩存文件有更新時(shí)纱昧,第一時(shí)間能使用到新的文件程奠;
- 緩存的文件要保持完整性,不使用被修改過(guò)的緩存文件输玷;
- 緩存的容量大小要能設(shè)置或控制,緩存文件不能因?yàn)榇鎯?chǔ)空間限制或過(guò)期被清除工育。
第4逃默,5屬于瀏覽器的內(nèi)部機(jī)制鹃愤,我們無(wú)法控制。
對(duì)于1完域,使用Cache-Control可以實(shí)現(xiàn)(Cache-Control的優(yōu)先級(jí)高于Expires)软吐。
對(duì)于2,使用Last-Modified或者Etag可以實(shí)現(xiàn)(兩者可以一起使用)吟税。
對(duì)于3凹耙,我們采用每次發(fā)布,在要緩存的資源文件名中加上版本號(hào)或文件MD5值字串的方法來(lái)實(shí)現(xiàn)(修改緩存文件的文件名)肠仪。
當(dāng)然肖抱,這里要注意一點(diǎn)就是“入口”文件(html文件)是被設(shè)置為不緩存的,如Google异旧,百度的html頁(yè)面: