数据传输
,节省了网费。性能
速度
最后修改时间
If-Modified-Since
:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向服务器请求时带上头If-Modified-Since。响应最新的资源
内容并返回200状态码;未更新
,告知浏览器继续使用所保存的缓存文件。let http = require('http');
let fs = require('fs');
let path = require('path');
let mime = require('mime');
http.createServer(function (req, res) {
let file = path.join(__dirname, req.url);
fs.stat(file, (err, stat) => {
if (err) {
sendError(err, req, res, file, stat);
} else {
let ifModifiedSince = req.headers['if-modified-since'];
if (ifModifiedSince) {
if (ifModifiedSince == stat.ctime.toGMTString()) {
res.writeHead(304);
res.end();
} else {
send(req, res, file, stat);
}
} else {
send(req, res, file, stat);
}
}
});
}).listen(8080);
function send(req, res, file, stat) {
res.setHeader('Last-Modified', stat.ctime.toGMTString());
res.writeHead(200, { 'Content-Type': mime.getType(file) });
fs.createReadStream(file).pipe(res);
}
function sendError(err, req, res, file, stat) {
res.writeHead(400, { "Content-Type": 'text/html' });
res.end(err ? err.toString() : "Not Found");
}
最后修改时间
, 这样就无法通过最后修改时间来判断文件是否更新了。精确到秒
。内容并未改变
。 我们不希望客户端认为这个文件修改了。CDN
服务器上的时候内容虽然一样,修改时间不一样。ETag是实体标签的缩写,根据实体内容生成的一段hash
字符串,可以标识资源的状态。当资源发生改变时,ETag也随之发生变化。
ETag是Web服务端产生的,然后发给浏览器客户端。
let http = require('http');
let fs = require('fs');
let path = require('path');
let mime = require('mime');
let crypto = require('crypto');
http.createServer(function (req, res) {
let file = path.join(__dirname, req.url);
fs.stat(file, (err, stat) => {
if (err) {
sendError(err, req, res, file, stat);
} else {
let ifNoneMatch = req.headers['if-none-match'];
let etag = crypto.createHash('sha1').update(stat.ctime.toGMTString() + stat.size).digest('hex');
if (ifNoneMatch) {
if (ifNoneMatch == etag) {
res.writeHead(304);
res.end();
} else {
send(req, res, file, etag);
}
} else {
send(req, res, file, etag);
}
}
});
}).listen(8080);
function send(req, res, file, etag) {
res.setHeader('ETag', etag);
res.writeHead(200, { 'Content-Type': mime.lookup(file) });
fs.createReadStream(file).pipe(res);
}
function sendError(err, req, res, file, etag) {
res.writeHead(400, { "Content-Type": 'text/html' });
res.end(err ? err.toString() : "Not Found");
}
Cache-Control:private, max-age=60, no-cache
let http = require('http');
let fs = require('fs');
let path = require('path');
let mime = require('mime');
let crypto = require('crypto');
http.createServer(function (req, res) {
let file = path.join(__dirname, req.url);
console.log(file);
fs.stat(file, (err, stat) => {
if (err) {
sendError(err, req, res, file, stat);
} else {
send(req, res, file);
}
});
}).listen(8080);
function send(req, res, file) {
let expires = new Date(Date.now() + 60 * 1000);
res.setHeader('Expires', expires.toUTCString());
res.setHeader('Cache-Control', 'max-age=60');
res.writeHead(200, { 'Content-Type': mime.lookup(file) });
fs.createReadStream(file).pipe(res);
}
function sendError(err, req, res, file, etag) {
res.writeHead(400, { "Content-Type": 'text/html' });
res.end(err ? err.toString() : "Not Found");
}