緩存是用來做什么的?
從我們在瀏覽器輸入地址再按下回車以后,瀏覽器會向服務(wù)器依次進(jìn)行DNS查詢辙培、初始化鏈接、發(fā)送請求以及等待服務(wù)器響應(yīng)邢锯,這些都會耗費(fèi)一定的時間扬蕊。這些過程結(jié)束之后,就會從服務(wù)器上下載相應(yīng)的內(nèi)容丹擎,這也會耗費(fèi)一定的時間尾抑。但是,如果我這次要下載的內(nèi)容和上一次一模一樣的話鸥鹉,那就可以從緩存中獲取這些內(nèi)容蛮穿,不必再從服務(wù)器上下載庶骄,進(jìn)而節(jié)約內(nèi)容的下載時間毁渗,這就是緩存的作用。設(shè)置Cache-Control
這是一種比較老的設(shè)置緩存的方法单刁,在服務(wù)端對相應(yīng)文件(比如:example.css)的響應(yīng)頭設(shè)置Cache-Control:public,max-age=3600,這樣灸异,以后在請求example.css時府适,就不會從服務(wù)器上下載文件而是從緩存里拿文件了。而緩存的時間就是上面設(shè)置的3600秒肺樟,在這3600秒之內(nèi)瀏覽器都只從緩存里讀取example.css檐春,過了3600秒才會再次從服務(wù)器上讀取文件。問題:如果我的example.css在這3600秒之內(nèi)發(fā)生變化了怎么辦么伯?如何讓變化了的example.css被下載而不是從緩存當(dāng)中讀取舊的example.css呢疟暖?
首先,默記以下真理:緩存都是依據(jù)url來實(shí)現(xiàn)的田柔。相應(yīng)的俐巴,只要把example.css改為example_1.css再重新設(shè)置下服務(wù)器路徑,那么瀏覽器就會根據(jù)新的url來請求相應(yīng)的文件硬爆,而不會再從緩存中拿了欣舵。當(dāng)然,這是非常舊的方法缀磕,五年前的前端是這么干的缘圈。至少有一個文件不應(yīng)該被緩存
如果html文件被緩存了,那么依托這個html文件的其它c(diǎn)ss和JS文件即便更改了路徑也無法請求到了袜蚕,這就要求這個html文件不應(yīng)該被緩存糟把。而瀏覽器對于用戶發(fā)的第一個請求默認(rèn)不緩存。這樣的話牲剃,其它的文件有更改了才會有被從服務(wù)器讀取的機(jī)會糊饱。Expires
一般不和Cache-Control共用。不推薦使用expires颠黎。它同樣是在響應(yīng)頭里添加一個Expires另锋,它的值是一個格林梅治時間,在這個時間之前會一直緩存狭归,這個時間之后會再次從服務(wù)器上下載相應(yīng)的文件夭坪。
Expires的問題及與Cache-Control的區(qū)別:Expires設(shè)置的一個絕對時間,比如說設(shè)置的緩存過期時間為2018年1月1日过椎,而它的對比時間是用戶的本地時間室梅。如果用戶把自己電腦的時鐘調(diào)快了一年的話,那這個緩存時間就無效了疚宇。相對的亡鼠,Cache-Control設(shè)置的相對時間,即當(dāng)內(nèi)容下載之后的時間敷待,不會受到用戶本地時間的影響间涵。
Last-modified
不推薦使用。它設(shè)置的是一個資源的最后修改時間榜揖,舉個例子勾哩,一個資源的Last-modified時間為2016年8月1日抗蠢,而今天的時間為2017年8月1日,當(dāng)瀏覽器讀取到這個資源的最后修改時間時思劳,它就會認(rèn)為迅矛,既然這個資源過去一年都沒有修改過,那么將來可能也不會修改潜叛,于是就會給一個啟發(fā)式的緩存時間秽褒,一般來說是Last-modified值距離現(xiàn)在時間的10%;ETag
想理解ETag就需要首先理解md5。md5是一種算法威兜,它接受一個輸入震嫉,是任意字符串,輸出是一個32位的字符串牡属。它的經(jīng)常用來定兩個不知道內(nèi)容的東西是否是相等的票堵。
當(dāng)在響應(yīng)頭中使用了ETag時,資源會被哈希(可以是md5也可以是其它算法)逮栅,這個哈希值是唯一的悴势。它和內(nèi)容一樣會返回給瀏覽器,當(dāng)瀏覽器下次再請求這個資源時措伐,之前的哈希值會在請求頭if-none-match一同發(fā)送給服務(wù)器特纤,服務(wù)器會再計(jì)算一次這個資源的哈希值,并且把它和瀏覽器請求過來的if-none-match值進(jìn)行比對侥加,如果二者是一樣的捧存,這就表示這個資源沒有更改過,那就從緩存中直接拿就行担败,如果值不一樣的話念祭,那就表示這個資源有更新鼠渺,那就從服務(wù)器下載這個資源的更新版本趁窃。
因?yàn)樗形募贾挥幸粋€哈希值旋廷,一個文件在被修改前后,它的哈希值是不一樣的狈网。