node实现缓存

内容:

1.缓存基本原理

2.node实现缓存

1.缓存基本原理

第一重要、缓存策略:

  • cache-control:用于控制缓存,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private
  • expires:失效时间

第二重要、缓存实现过程:

  • 第一次Server->Client:"Last-Modified: Sat, 02 Dec 2017 04:03:14 GMT"  --> 服务端告诉客户端资源修改的时间
  • 第二次Client->Server:"If-Modified-Since: Sat, 02 Dec 2017 04:03:14 GMT"  --> 浏览器告诉服务器自己缓存的资源的修改时间
  • 第二次Server->Client:200 || 304  --> 服务器根据两者时间是否相同决定返回200(返回新资源)还是304(叫浏览器用自己缓存的资源)

注意:

2.node实现缓存

源码:

 1 const http=require('http');
 2 const fs=require('fs');
 3 const url=require('url');
 4 
 5 // 连续两次访问:  http://localhost:8080/1.html    第一次是200  第二次是304
 6 http.createServer((req, res)=>{
 7     let {pathname}=url.parse(req.url);
 8 
 9     //获取文件日期
10     fs.stat(`www${pathname}`, (err, stat)=>{
11         if(err){
12             res.writeHeader(404);
13             res.write('Not Found');
14             res.end();
15         }else{
16             // 请求头中有if-modified-since -> 不是第一次请求,之前浏览器中缓存了该页面
17             if(req.headers['if-modified-since']){
18                 let oDate=new Date(req.headers['if-modified-since']);
19                 let time_client=Math.floor(oDate.getTime()/1000);
20                 let time_server=Math.floor(stat.mtime.getTime()/1000);
21 
22                 if(time_server>time_client){      // 服务器的文件时间 > 客户端手里的版本
23                     sendFileToClient();
24                 }else{
25                     res.writeHeader(304);
26                     res.write('Not Modified');
27                     res.end();
28                 }
29             }
30             // 请求头中没有if-modified-since -> 第一次请求 -> 直接返回要的文件
31             else{
32                 sendFileToClient();
33             }
34 
35             // 直接返回文件
36             function sendFileToClient(){
37                 //发送
38                 let rs=fs.createReadStream(`www${pathname}`);
39 
40                 res.setHeader('Last-Modified', stat.mtime.toGMTString());
41 
42                 //输出
43                 rs.pipe(res);
44 
45                 rs.on('error', function(err){
46                     res.writeHeader(404);
47                     res.write('Not Found');
48                     res.end();
49                 });
50             }
51         }
52     });
53 }).listen(8080);

原理:

  • 服务端第一次向客户端发送资源时设置文件修改时间:setHeader('Last-Modified', stat.mtime.toGMTString())
  • 之后客户端向浏览器请求时服务端检查请求头中是否有if-modified-since:
  • 如果有if-modified-since就判断服务器时间是否大于浏览器时间(若大于说明服务端文件已经修改就将新修改的文件返回,否则就返回304浏览器会直接使用原先缓存的资源)
  • 如果没有if-modified-since就直接返回文件并像最上面那样设置文件修改时间

另外还可以设置缓存:

 1 // 具有缓存控制的服务器 --> 设置Cache-Control(no-cache)
 2 const http=require('http');
 3 const fs=require('fs');
 4 const url=require('url');
 5 
 6 // 连续两次访问:  http://localhost:8080/1.html    第一次是200  第二次是304
 7 http.createServer((req, res)=>{
 8     let {pathname}=url.parse(req.url);
 9 
10     //获取文件日期
11     fs.stat(`www${pathname}`, (err, stat)=>{
12         if(err){
13             res.writeHeader(404);
14             res.write('Not Found');
15             res.end();
16         }else{
17             // 请求头中有if-modified-since -> 不是第一次请求,之前浏览器中缓存了该页面
18             if(req.headers['if-modified-since']){
19                 let oDate=new Date(req.headers['if-modified-since']);
20                 let time_client=Math.floor(oDate.getTime()/1000);
21                 let time_server=Math.floor(stat.mtime.getTime()/1000);
22 
23                 if(time_server>time_client){      // 服务器的文件时间 > 客户端手里的版本
24                     sendFileToClient();
25                 }else{
26                     res.writeHeader(304);
27                     res.write('Not Modified');
28                     res.end();
29                 }
30             }
31             // 请求头中没有if-modified-since -> 第一次请求 -> 直接返回要的文件
32             else{
33                 sendFileToClient();
34             }
35 
36             // 直接返回文件
37             function sendFileToClient(){
38                 //发送
39                 let rs=fs.createReadStream(`www${pathname}`);
40                 
41                 // 设置缓存
42                 res.setHeader('Cache-Control', 'no-cache');
43                 res.setHeader('Last-Modified', stat.mtime.toGMTString());
44 
45                 //输出
46                 rs.pipe(res);
47 
48                 rs.on('error', function(err){
49                     res.writeHeader(404);
50                     res.write('Not Found');
51                     res.end();
52                 });
53             }
54         }
55     });
56 }).listen(8080);
57                 
原文地址:https://www.cnblogs.com/wyb666/p/9703716.html