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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

缓存浅析

發布時間:2024/1/17 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 缓存浅析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概念

緩存是一種保存資源副本并在下次請求時直接使用該副本的技術。——MDN

緩存能緩解服務器壓力,提高響應速度,提升用戶體驗。

以下討論的緩存是針對對img/script/css資源而言的,且緩存策略都是依靠 http 報文的首部來實現。

實驗

搭建實驗環境

編寫 html 文件

<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><link rel="icon" href="data:;base64,="><title>緩存</title> </head><body><img style="width:400px;" src="sun.jpg"><div>緩存實驗</div> </body></html>

服務端代碼

const path = require('path') const url = require('url') const fs = require('fs') const zlib = require('zlib')const img = fs.readFileSync(path.resolve(__dirname, './static/sun.jpg'), 'binary')http.createServer((req, res) => {const html = fs.createReadStream(path.resolve(__dirname, './static/index.html'))let {pathname} = url.parse(req.url)if (pathname === '/') {res.writeHead(200, {'Content-Type': 'text/html','Content-Encoding': 'gzip'})html.pipe(zlib.createGzip()).pipe(res)} else if (pathname === '/sun.jpg') {res.writeHead(200, {'Content-Type': 'image/jpeg'})res.write(img, 'binary')res.end()} else {res.end(pathname)} }).listen(3210)

訪問 http://localhost:3210 , 看到相應的文檔和圖片,且無論刷新多少次,sun.jpg 的 Status 和 Size 都不變。控制臺里勾選 Preserve log

Cache-Control

通過在服務端設置相應首部 Cache-Control 可以控制緩存行為,例如

  • Cache-Control: no-cache, 告訴瀏覽器,下次請求該資源時,不直接使用緩存,而是向服務端發送請求,服務端會根據請求,判斷本地的資源是否過期
  • Cache-Control: no-store, 告訴瀏覽器,不要緩存該資源
  • Cache-Control: max-age=age, 告訴瀏覽器,這個資源有效的時長 age,在該時間范圍內,如果需要該資源,直接從本地取,不要煩我(向我發送請求)

修改服務端代碼

設置圖片緩存時長 30s

res.writeHead(200, {'Content-Type': 'image/jpeg','Cache-Control': 'max-age=30'})

快速刷新頁面2次,超過30s后,再刷新一次

三次刷新結果在控制臺顯示的情況如下


其中第二次請求 sun.jpg 的請求情況如下,200 OK (from memory cache),第三次請求 sun.jpg 則又是從服務端獲取圖片,顯示資源 1.6M。

Last-Modified & If-Modified

現在的情形是這樣的,30s到了,瀏覽器向服務端發出 sun.jpg 的請求,但服務器并沒有更新該資源,所以服務器告訴瀏覽器,“我沒有修改該資源,你還是用你本地的吧,我就不再發給你了”。這些通過 Last-Modified 和 If-Modified-Since 來實現。

瀏覽器第一次向服務端請求 sun.jpg,服務端不僅返回 sun.jpg,還通過響應首部的 Last-Modified(瀏覽器自動添加),告訴瀏覽器該資源最后修改的時間。

下次瀏覽器再次請求 sun.jpg,會通過請求首部的 If-Modified-Since, 把自己手上這個資源最后修改的時間告訴服務端,服務端通過這個時間,判斷瀏覽器本地的資源是否是最新的,若是,則返回 304(not modified) 和響應頭部即可,不用返回圖片;若不是,則返回 200 和圖片。

修改服務端代碼

const http = require('http') const path = require('path') const url = require('url') const fs = require('fs') const zlib = require('zlib')const img = fs.readFileSync(path.resolve(__dirname, './static/sun.jpg'), 'binary') let date = new Date() let lastModified = date.toUTCString()http.createServer((req, res) => {const html = fs.createReadStream(path.resolve(__dirname, './static/index.html'))let {pathname} = url.parse(req.url)if (pathname === '/') {res.writeHead(200, {'Content-Type': 'text/html','Content-Encoding': 'gzip'})html.pipe(zlib.createGzip()).pipe(res)} else if (pathname === '/sun.jpg') {if (req.headers['if-modified-since'] === lastModified) {res.writeHead(304, {'Content-Type': 'image/jpeg','Cache-Control': 'max-age=30','Last-Modified': lastModified})res.end()} else {res.writeHead(200, {'Content-Type': 'image/jpeg','Cache-Control': 'max-age=30','Last-Modified': lastModified})res.write(img, 'binary')res.end()}} else {res.end(pathname)} }).listen(3210)

瀏覽器刷新一次,30s內,再刷新一次,30s后再刷新一次

三次刷新的結果在控制臺里顯示如下,最后一次還有 189B 是服務端響應頭部的大小,178ms 里包含了服務端比較修改時間,返回響應頭部的時間。

且最后一次請求 sun.jpg 的請求情形如下

ETag & If-None-Match

Etag 和 If-None-Match 起到的作用和上文中 Last-Modified 和 If-Modified 差不多,區別在于 Etag 是服務端上通過算法給資源計算出的唯一標示,當資源修改時,該標示會發生變化。服務端通過響應首部 Etag 將該標示告訴瀏覽器,瀏覽器再下一次請求該資源時,會通過請求首部 If-None-Match 帶上該標示,服務端會比較請求中的標示和該資源最新的標示,如果一樣,證明瀏覽器擁有的該資源是最新的,僅返回304和響應頭部,否則返回200和整個資源。

強制刷新

常使用的強制刷新就是通過修改請求首部來實現的

將 Cache-Control 和 Pragma 設為 no-cache,去除 If-Modified, If-None-Match

盜個圖,HTTP緩存控制小結

快速更新

很多js文件或css文件的文件名會帶有文件指紋或版本號,通過改變文件名,讓瀏覽器以為請求的新的未緩存的資源從而實現快速更新。

參考

  • HTTP緩存控制小結
  • [淺談瀏覽器http的緩存機制](http://www.cnblogs.com/vajoy/...

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。