日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HTTP—缓存

發(fā)布時間:2023/12/9 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HTTP—缓存 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

1. ETag

HTTP 1.1中引入了ETag來解決緩存的問題。ETag全稱是Entity Tag,由服務(wù)端生成,服務(wù)端可以決定它的生成規(guī)則。如果根據(jù)文件內(nèi)容生成散列值。那么條件請求將不會受到時間戳的改動造成帶寬浪費。下面是根據(jù)內(nèi)容生成散列值的方法:

1 var getHash = function(str) { 2 var shasum = crypto.createHash('sha1'); 3 return shasum.update(str).digest('base64'); 4 }

與If-Modified-Since/Last-Modified不同的是,ETag的請求和響應(yīng)是If-None-Match/ETag。瀏覽器在收到帶有ETag:'14-389247298365'字段的響應(yīng)頭后,會在后面的請求中將其設(shè)置在請求頭中:If-None-Match: '14-389247298365'。服務(wù)器端收到帶If-None-Match: '14-389247298365'的報頭后,會進行如下判斷來決定返回新的內(nèi)容還是只響應(yīng)一個304狀態(tài)碼讓瀏覽器使用本地緩存版本:

1 var handle = function(req, res) { 2 fs.readFile(filename, function(err, file){ 3 var hash = getHash(file); 4 var noneMatch = req['if-none-match']; 5 if (hash === noneMatch) { 6 res.writeHead(304, "Not Modified"); 7 res.end(); 8 } else { 9 res.setHeader("ETag", hash); 10 res.writeHead(200, "OK"); 11 res.end(file); 12 } 13 }) 14 }

2.?Last-Modified

通常來說,如果請求頭中不包含ETag,服務(wù)端會通過判斷Last-Modified值來決定響應(yīng)304狀態(tài)碼還是新的文件內(nèi)容。Last-Modified顧名思義指的是文件的最后一次修改時間。與ETag一樣,在瀏覽器首次訪問站點后,服務(wù)端會在其響應(yīng)頭中設(shè)置一個Last-Modified的字段,它的值是一個UTC格式的時間字符串。隨后,在瀏覽器對站點的第二次訪問中,會在其請求頭中設(shè)置一個If-Modified-Since,其值就是上一次返回的Last-Modified的值。服務(wù)器端會根據(jù)這個值是否與其本地文件的最后一次修改時間相同來判斷是否使用緩存。代碼如下:

1 var handle = function(req, res) { 2 fs.stat(filename, function(err, stat){ 3 var lastModified = stat.mtime.toUTCString(); 4 if (lastModified === req.headers['if-modified-since']) { 5 res.writeHead(304, "Not Modified"); 6 res.end(); 7 } else { 8 fs.readFile(filename, function(err, file){ 9 var lastModified = stat.mtime.toUTCString(); 10 res.setHeader("Last-Modified", lastModified); 11 res.writeHead(200, "OK"); 12 res.end(file); 13 }); 14 } 15 }) 16 }

3. Expires 和 Cache-Control

以上兩種的緩存判斷都需要客戶端向服務(wù)端先發(fā)送一個條件請求,根據(jù)返回來決定是否使用緩存。需要一定的時間開銷和帶寬。而實際上瀏覽器最先判斷的是Expires 和 Cache-Control。在服務(wù)端相應(yīng)里設(shè)置Expires 或 Cache-Control,瀏覽器會根據(jù)該值進行緩存。Expires是一個GMT格式的時間字符串。瀏覽器再接收到這個過期值后,只要本地還存在對應(yīng)緩存文件,在到期時間之前它都不會再發(fā)起請求。但它的缺陷是瀏覽器與服務(wù)器之間的時間可能不一致,導(dǎo)致文件提前過期或已經(jīng)過期卻還沒刪除。

而Cache-Control恰恰解決了這個問題:

1 var handle = function(req, res) { 2 fs.readFile(filename, function(err, file){ 3 res.setHeader("Cache-Control", "max-age=" + 10*365*24*60*60); 4 res.writeHead(200, "OK"); 5 res.end(file); 6 }); 7 }

上面的代碼為Cache-Control設(shè)置了max-age值為10年,max-age會告訴瀏覽器文件多長時間后過期,進行倒計時式的計算。這樣就可以避免客戶端與服務(wù)器端時間不一致帶來的問題了。此外Cache-Control還可以public、private、no-cache、no-store等更精細地控制緩存的選項。HTTP1.0時還不支持max-age,如今的服務(wù)端在模塊的支持下多半同時對Expires 和 Cache-Control進行支持,如果瀏覽器中兩個值都存在且同時被支持,max-age會覆蓋Expires。

這兩種方法雖然節(jié)省了帶寬和請求時間,但其缺陷是當(dāng)服務(wù)端的文件內(nèi)容進行了更新時,無法通知客戶端更新。因為瀏覽器是根據(jù)URL進行緩存的,所以我們一般在對靜態(tài)資源使用緩存時也會對其設(shè)定版本號。使得客戶端能請求到新的內(nèi)容。一般更新機制有如下兩種方式:

  • 每次發(fā)布,web應(yīng)用或靜態(tài)資源的路徑中附帶對應(yīng)的版本號:http://url.com/?v=20141216
  • 每次發(fā)布,web應(yīng)用或靜態(tài)資源的路徑中附帶文件內(nèi)容的hash碼:http://url.com/?hash=sdasd4d

因為文件內(nèi)容更新并不意味著新的版本。所以使用hash值得方式會更加妥當(dāng)一些。

轉(zhuǎn)載于:https://www.cnblogs.com/WhiteCusp/p/4168304.html

總結(jié)

以上是生活随笔為你收集整理的HTTP—缓存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。