内容:

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);

node实现缓存的更多相关文章

  1. node.js缓存处理方式

    Node.JS缓存处理分为客户端和服务端两个部分. 客户端的缓存主要是利用浏览器对HTTP协议响应头中cache-control和expires字段的支持.浏览器在得到明确的响应头后,会将文件缓存在本 ...

  2. Node.js缓存

    Node.js Buffer(缓冲区) JavaScript 语言自身只有字符串数据类型,没有二进制数据类型. 但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 ...

  3. 深入浅出node(2) 模块机制

    这部分主要总结深入浅出Node.js的第二章 一)CommonJs 1.1CommonJs模块定义 二)Node的模块实现 2.1模块分类 2.2 路径分析和文件定位 2.2.1 路径分析 2.2.2 ...

  4. 缓存淘汰算法--LRU算法

    1. LRU1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是"如果数据最近被访问过,那么将来被访问的几率也 ...

  5. JavaScript实现TwoQueues缓存模型

    本文所指TwoQueues缓存模型,是说数据在内存中的缓存模型. 无论何种语言,都可能需要把一部分数据放在内存中,避免重复运算.读取.最常见的场景就是JQuery选择器,有些Dom元素的选取是非常耗时 ...

  6. node学习笔记

    一.准备(github地址) 什么是Javascript? ... Javascript能做什么? ..... 浏览器中的Javascript可以做什么? 操作DOM(增删改查) AJAX/跨域 BO ...

  7. JPA,EclipseLink 缓存机制学习(一) 树节点搜索问题引发的思考

    最近在项目在使用JPA+EclipseLink 的方式进行开发,其中EclipseLink使用版本为2.5.1.遇到一些缓存方面使用不当造成的问题,从本篇开始逐步学习EclipseLink的缓存机制. ...

  8. 浅析LRU(K-V)缓存

    LRU(Least Recently Used)算法是缓存技术中的一种常见思想,顾名思义,最近最少使用,也就是说有两个维度来衡量,一个是时间(最近),一个频率(最少).如果需要按优先级来对缓存中的K- ...

  9. Node.js的模块载入方式与机制

    Node.js中模块可以通过文件路径或名字获取模块的引用.模块的引用会映射到一个js文件路径,除非它是一个Node内置模块.Node的内置模块公开了一些常用的API给开发者,并且它们在Node进程开始 ...

随机推荐

  1. Python模块 实现过渡性模块重载

    本文是在阅读Python 学习手册后  感觉比较不错的一个实现模块重载的一个模块,该模块可以实现对已经加载在运行程序中的模块实现重新加载,并且该模块可以递归的实现对要重新加载的模块内所引用的其它模块的 ...

  2. matlab fopen()

    file=dir('/home/wang/Desktop/trainset/others/'); :length(file) path= strcat('/home/wang/Desktop/trai ...

  3. 【poj3169】【差分约束+spfa】

    题目链接http://poj.org/problem?id=3169 题目大意: 一些牛按序号排成一条直线. 有两种要求,A和B距离不得超过X,还有一种是C和D距离不得少于Y,问可能的最大距离.如果没 ...

  4. DOS命令下使用sqlite3 命令中文乱码的解决办法

    windows cmd窗口无法显示中文,不一定数据库中存储的就是乱码——多数情况只是显示问题,可以通过以下方式解决: 1.退出dos 或者重新开启在CMD窗口,输下:chcp 65001 然后回车确定 ...

  5. Django中提供了6种缓存方式

    开发调试 内存 文件 数据库 Memcache缓存(python-memcached模块) Memcache缓存(pylibmc模块) 1. 开发调试 1 2 3 4 5 6 7 8 9 10 11 ...

  6. 剑指offer-矩形覆盖-斐波那契数列(递归,递推)

    class Solution { public: int rectCover(int number) { if(number==0 || number==1||number==2) return nu ...

  7. Web Js推断键盘出发事件

      window.document.onkeydown = disableRefresh; function disableRefresh(evt){ evt = (evt) ? evt : wind ...

  8. MSDN Windows XP Professional x64 Edition with SP2 +VL简体中文语言包+序列号

    [资源名称]---Windows XP Professional x64 Edition with SP2 - VL (English)[资源类型]---ISO镜像[资源语言]---英语+简体中文[杀 ...

  9. c++标准库的所有类型

    标准库的组成:    前言就到此为止.从最宏观的层面上看,C++标准库由十个部分组成:语言支持.诊断.通用工具.字符串.本地化.容器.迭代器.通用算法.数值算法和I/O. 头文件组成:    C++ ...

  10. linux ssh公钥免密码登录

    ssh 无密码登录要使用公钥与私钥.linux下可以用用ssh-keygen生成公钥/私钥对,下面我以CentOS为例. 一.SSH公钥登录原理 在平时工作中我们经常要远程登录服务器,这就要用到SSH ...