• 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                 
  • 相关阅读:
    scrapy爬取某网站,模拟登陆过程中遇到的那些坑
    Linux平台安装MongoDB
    Oracle HAVING子句
    oracle查找重复记录-转
    PLSQL存储过程(基础篇)-转
    oracle for update和for update nowait的区别
    Oracle两个数据库互相访问,DBLink使用-转
    中国人素质低的根本原因
    威胁李嘉诚是愚蠢的
    回归农村,这才是我想要的生活
  • 原文地址:https://www.cnblogs.com/wyb666/p/9703716.html
Copyright © 2020-2023  润新知