在說緩存那些事以前,必須對http經常使用的狀態碼有一些簡單的瞭解:html
- 200 請求已成功,請求所但願的響應頭或數據體將隨此響應返回。出現此狀態碼是表示正常狀態
- 304 Not Modified 強制緩存
- 固然還有不少其餘的狀態碼,以上200 和 304是本篇文章重點講到的。
其實就是經過設置http的頭信息來進行設置各類緩存的web
//HTTP 1.1 引入的
//Cache-Control: no-cache/max-age=600
let http = require('http')
let url = require('url')
let util = require('util')
let fs = require('mz/fs')
let stat = util.promisify(fs.stat);
let path = require('path');
let p = path.resolve(__dirname);
http.createServer(async function(req, res) {
let {pathname} = url.parse(req.url);
let realPath = path.join(p, pathname);
console.log(realPath)
try{
let statObj = await fs.stat(realPath);
console.log(statObj)
res.setHeader('Cache-Control','max-age=10') //強制緩存 10s內不須要再次請求服務器
//res.setHeader('Cache-Control','no-cache')
res.setHeader('Content-Type',require('mime').getType(realPath)+';charset=utf8')
fs.createReadStream(realPath).pipe(res)
}catch(e) {
res.statusCode = 404;
res.end('404')
}
}).listen(3000)
咱們請求一個本地的文件
// index.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">
<title>Document</title>
</head>
<body>
<img src="/agree.png"/>
</body>
</html>
//在瀏覽器打開localhost:3000/index.html
//能夠看到狀態碼是200,這個200有兩種狀況一種是直接讀取緩存的
//1. (from memory cache) 緩存在內存當中;(from disk cache) 緩存在硬盤中
//2. 真的是從服務器中拉取過來的
複製代碼
//Expires:Sun, 22 Jul 2018 02:43:42 GMT
//備註:若是Cache-Control和Expires同時存在,Cache-Control說了算
res.setHeader('Expires', new Date(Date.now() + 10*1000).toGMTString()) //強制緩存的另外一種方式,另外強調一點:主網頁只有對比緩存沒有強制緩存
複製代碼
//對比緩存 爲了更加明顯的看到對比緩存,咱們將在如下的代碼中都將強制緩存關閉
//res.setHeader('Cache-Control','no-cache')
//響應頭設置了res.setHeader('Last-Modified',statObj.ctime.toGMTString())
//請求頭就會帶上req.headers['if-modified-since']
let http = require('http')
let url = require('url')
let util = require('util')
let fs = require('mz/fs')
let stat = util.promisify(fs.stat);
let path = require('path');
let p = path.resolve(__dirname);
http.createServer(async function(req, res) {
let {pathname} = url.parse(req.url);
let realPath = path.join(p, pathname);
console.log(realPath)
try{
let statObj = await fs.stat(realPath);
console.log(statObj)
// res.setHeader('Cache-Control','max-age=10') //強制緩存 10s內不須要再次請求服務器
res.setHeader('Cache-Control','no-cache')
res.setHeader('Content-Type',require('mime').getType(realPath)+';charset=utf8')
res.setHeader('Expires', new Date(Date.now() + 10*1000).toGMTString()) //強制緩存 由於上面設置了no-cache,因此這裏的設置其實無效
let since = req.headers['if-modified-since'];
if (since === statObj.ctime.toGMTString()) {
res.statusCode = 304 //服務器的緩存
res.end();
} else {
res.setHeader('Last-Modified',statObj.ctime.toGMTString())
fs.createReadStream(realPath).pipe(res)
}
}catch(e) {
res.statusCode = 404;
res.end('404')
}
}).listen(3000)
//在瀏覽器打開localhost:3000/index.html 刷新看到就是304,咱們返回狀態碼304,瀏覽器就乖乖地去讀緩存中的文件了。
//咱們稍微改動一下index.html就能夠看到 200
複製代碼
//對比緩存
//Etag內容的標識
// 響應頭設置了res.setHeader('Etag',statObj.size.toString()); 這裏設置的是文件大小
//請求頭就會帶上req.headers['if-none-match'];
//
let http = require('http');
let util = require('util');
let fs = require('fs');
let stat = util.promisify(fs.stat);
let url = require('url');
let path = require('path');
let p = path.resolve(__dirname);
// 比較內容 stat.size (不靠譜)
// 第一次請求Etag:內容的標識
// 第二次在請求個人時候 if-none-match
http.createServer(async function(req,res){
let {pathname} = url.parse(req.url);
let realPath = path.join(p,pathname);
try{
let statObj = await stat(realPath);
console.log(realPath)
res.setHeader('Cache-Control','no-cache');
let match = req.headers['if-none-match'];
if(match){
if(match === statObj.size.toString()){
res.statusCode = 304;
res.end();
}else{
res.setHeader('Etag',statObj.size.toString());
fs.createReadStream(realPath).pipe(res);
}
}else{
res.setHeader('Etag',statObj.size.toString());
fs.createReadStream(realPath).pipe(res);
}
}catch(e){
res.statusCode = 404;
res.end(`not found`);
}
}).listen(3000);
複製代碼
- 設置強制緩存的方式就是 res.setHeader('Cache-Control','max-age=10')
- res.setHeader('Expires', new Date(Date.now() + 10*1000).toGMTString())
- 以上兩種以第一種方式取決定做用
- 經過時間對比 Last-Modified ---- if-modified-since
- 經過標識對比 Etag ---- if-none-match
以上就是web緩存的部份內容,不足之處歡迎各位提出寶貴的意見或建議,也但願能幫助到你從中得到一些知識,謝謝你們的關注!瀏覽器