缓存

浏览器缓存(Brower Caching)是浏览器对之前请求过的文件进行缓存,以便下一次访问时重复使用,节省带宽,提高访问速度,降低服务器压力

缓存位置分类

memory cache:内存中的缓存,关闭浏览器则清空,一般存储一些js库

disk cache:硬盘中的缓存,关闭浏览器不会马上清空,一般存储大文件,比如 图片资源,iconFont这类的图标文件库

两者的区别:

  1. 读取速度 :memory cache缓存的是当前解析过了的文件在浏览器tab进程里,下次运行使用时的可以快速读取;

              disk cache直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O(读取)操作,然后重新解析缓存内容,速度比内存缓存慢

  2. 时效性:memory cache是存在tab的进程里,tab关闭,则清空;

            disk cache:被清空的时机我还不知道(希望有人可以补充)

  3. 优先级:memory cache大于disk cache

  对于大文件来说,大概率是不存储在memory中的,反之优先,代码角度目前好像也无法控制浏览器缓存位置

缓存设置header

cache-control

 1.   cache-control:max-age=10//10秒内重新发的请求都直接命中强缓存,无需向服务器发起请求,读取浏览器缓存即可
 2.   Cache-Control:no-cache //禁止强制缓存,每次都向服务器发起请求,同时也会存在浏览器缓存中 (走协商缓存了基本)
 3.   Cache-Control:no-store //每次都请求服务器,且不缓存在浏览器中,等同于没有缓存 
复制代码

Expires:

兼容低版本浏览器,这个就是设置绝对时间,获取的是服务器的当前时间和浏览器当前时间做比对(通常存在偏差,是http1.0的产物),和 cache-control同时存在时,cache-control优先级更高

  • last-modified:协商缓存的时候用 和If-Modified-Since,成对出现;If-Modified-Since请求头的值对应上一次服务器的响应头last-modified的值,拥有提供服务器比对请求资源修改时间,相等,则命中协商缓存返回304,浏览器读取缓存即可
  • Etag:资源标识(也有说时指纹,通常是一个md5值),协商缓存时候用,比较文件是否修改;和If-None-Match 成对出现

Etag主要为了解决 Last-Modified 无法解决的一些问题。

1. 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;

2. 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since无法检查到如此精细

3. 某些服务器不能精确的得到文件的最后修改时间;

4.Etag与Last-modify同时存在 Etag优先级比较

实际项目:html不允许缓存,html里引用的js有唯一的版本号做依据,再次访问的时候 访问最新的html,引用的js或其他文件版本号未修改则直接用本地缓存

node实现静态文件缓存

文件结构

public对应我们测试用的静态资源

强缓存

思路

  • 创建服务
  • 首次请求 解析请求路径, fs.createReadStream().pipe() 读取文件
  • 设置响应头Cache-Contro:max-age=10 强缓存的相对时间

代码实现

const http = require("http");
const url = require("url");
const fs = require("fs");
const path = require("path");
// 接收文件路径 返回该文件对应的文件类型格式
const mime = require("mime");//npm i mime 

const server = http.createServer((req, res) => {
  let { pathname, query } = url.parse(req.url, true);
  //__dirname 当前文件所在的文件夹所处的绝对路径 和请求路径拼接
  let filePath = path.join(__dirname, "public", pathname);
  console.log(req.url);//10s内反复刷新页面,查看是否持续打印,命中强缓存则10s打印一次
  // 设置头部 缓存信息,规定的缓存时间内,客户端无需再向服务器发起请求
  res.setHeader("Cache-Control", "max-age=10"); // 设置缓存时常;请求的当前时间 max-age 的相对时间内,优先级比Expires高
  res.setHeader("Expires", new Date(Date.now()   10).toUTCString()); //兼容低版本浏览器,这个就是设置绝对时间,获取的是服务器的当前时间
  // 获取请求路径 判断是文件还是文件目录
  fs.stat(filePath, function (err, statObj) {
    // url解析错误,则请求错误 没有找到对应url资源 返回404
    if (err) {
      res.statusCode = 404;
      res.end("NOT FOUND");
    } else {
      // 如果是文件,用可读流 管道 pipe 进行文件内容读取,利用mime 获取文件内容格式,并设置编码规范为utf-8
      if (statObj.isFile()) {
        fs.createReadStream(filePath).pipe(res);
        res.setHeader(
          "Content-Type",
          mime.getType(filePath)   ";charset=utf-8"
        );
      } else {
        // 如果是文件目录 找到 目录下对应的index.html
        let htmlPath = path.join(filePath, "index.html");
        // fs.access判断拼接的路径是否可访问
        fs.access(htmlPath, function (err) {
          if (err) {
            // 不可访问 设置 状态码404
            res.statusCode = 404;
            res.end("NOT FOUND");
          } else {
            //可访问,用可读流加管道 pipe 进行文件内容读取
            fs.createReadStream(htmlPath).pipe(res);
            res.setHeader("Content-Type", "text/html;charset=utf-8");
          }
        });
      }
    }
  });
  // 写到这里 可以 nodemon cache.js  启动服务 查看 http://localhost:3000/ 
});
server.listen(3000, () => {
  console.log("server start 3000");
});

效果展示

协商缓存

成功

思路

  • 创建服务
  • 首次请求 解析请求路径, fs.createReadStream().pipe() 读取文件
  • 设置响应头Last-modified 返回浏览器
  • 再次请求,比较浏览器if-last-modified 和当前资源修改时间,相等则命中协商缓存,返回响应码304,反之返回路径对应的最新资源,和响应码200

代码实现

const http = require("http");
const url = require("url");
const fs = require("fs");
const path = require("path");
const mime = require("mime");


  let filePath = path.join(__dirname, "public", pathname);
  console.log(req.url);
  fs.stat(filePath, function (err, statObj) {
    if (err) {
      res.statusCode = 404;
      res.end("NOT FOUND");
    } else {
      if (statObj.isFile()) {
        // 判断 浏览器请求的文件路径 的change 时间 通过statObj.ctime
        const ctime = statObj.ctime.toUTCString();
        // 浏览器请求头if-modified-since ===文件上次的修改时间 ,命中协商缓存,则返回 304 浏览器缓存中请求资源
        if (req.headers["if-modified-since"] === ctime) {
          res.statusCode = 304; //去浏览器缓存中找
          res.end(); //
        } else {
          //  if-modified-since !==文件上次的修改时间,响应头Last-modified 设置 当前请求文件的 修改时间 做下次 浏览器请求的last-modify-since的对应值
          res.setHeader("Last-modified", ctime);
          fs.createReadStream(filePath).pipe(res);
          res.setHeader(
            "Content-Type",
            mime.getType(filePath)   ";charset=utf-8"
          );
        }
      } else {
        fs.access(htmlPath, function (err) {
          if (err) {
            // 不可访问 设置 状态码404
            res.statusCode = 404;
            res.end("NOT FOUND");
          } else {
            fs.createReadStream(htmlPath).pipe(res);
            res.setHeader("Content-Type", "text/html;charset=utf-8");
          }
        });
      }
    }
  });
  // 写到这里 可以 nodemon cache2.js       启动服务 查看 http://localhost:3000/ 
});
server.listen(3000, () => {
  console.log("server start 3000");
});

效果展示

每次刷新页面都会执行  console.log(req.url); 请求了服务器但服务器返回304 命中协商缓存 浏览器直接读取缓存资源即可

成功

总结

到此这篇关于如何利用node实现静态文件缓存的文章就介绍到这了,更多相关node静态文件缓存内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

如何利用node实现静态文件缓存详解的更多相关文章

  1. 详解使用双缓存解决Canvas clearRect引起的闪屏问题

    这篇文章主要介绍了详解使用双缓存解决Canvas clearRect引起的闪屏问题的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. HTML5 Web缓存和运用程序缓存(cookie,session)

    这篇文章主要介绍了HTML5 Web缓存和运用程序缓存(cookie,session),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. 详解前端HTML5几种存储方式的总结

    本篇文章主要介绍了前端HTML5几种存储方式的总结 ,主要包括本地存储localstorage,本地存储sessionstorage,离线缓存(application cache),Web SQL,IndexedDB。有兴趣的可以了解一下。

  5. ios – 使用带有NodeJs HTTPS的certificates.cer

    我为IOS推送通知生成了一个.cer文件,我希望将它与NodeJSHTTPS模块一起使用.我发现HTTPS模块的唯一例子是使用.pem和.sfx文件,而不是.cer:有解决方案吗解决方法.cer文件可以使用两种不同的格式进行编码:PEM和DER.如果您的文件使用PEM格式编码,您可以像使用任何其他.pem文件一样使用它(有关详细信息,请参见Node.jsdocumentation):如果您的文件使

  6. 在iOS上,缓存绘制的屏幕图像并显示它的最快方法是什么?

    我没有让drawRect每次重绘数千个点,我认为有几种方法可以“在屏幕上缓存图像”和任何其他绘图,我们将添加到该图像,并在drawRect时显示该图像:>使用BitmapContext并绘制到位图,并在drawRect中绘制此位图.>使用CGLayer并在drawRect中绘制CGLayer,这可能比方法1快,因为此图像缓存在图形卡中(并且它不会计入iOS上“内存警告”的RAM使用情况?

  7. ios – NSURLCache和数据保护

    我正在尝试保护存储在NSURLCache中的敏感数据.我的应用程序文件和CoreDatasqlite文件设置为NSFileProtectionComplete.但是,我无法将NSURLCache文件数据保护级别更改为NSFileProtectionCompleteUntilFirstUserAuthentication以外的任何其他级别.这会在设备锁定时暴露缓存中的任何敏感数据.我需要缓存响应,以

  8. iOS Safari多久会清除一次缓存?

    我使用移动Safari缓存来存储我想要持久化的一些数据,所以我希望它们能够在Safari重启和iOS重启后继续存在.但是我已经阅读了somenew和someold报告,Safari在Safari重新启动时清除了它的缓存.但我对Safari8.3的非科学测试表明,有时这个缓存实际上不仅可以在应用程序重启后生存,而且甚至可以重启iOS(!).所以我在这一点上有点困惑.iOSSafari缓存清除的规则是否记录在某处?你们中有谁知道他们并且可以向我解释他们吗?解决方法希望有人发现我错了但是……

  9. ios – 如何获取缓存图像SDWebImage的数据

    我正在使用SDWebImage库来缓存我的UICollectionView中的Web图像:但我想将缓存的图像本地保存在文件中,而不是再次下载它们有没有办法获取缓存图像的数据解决方法SDWebImage默认自动缓存下载的图像.您可以使用SDImageCache从缓存中检索图像.当前应用会话有一个内存缓存,它会更快,并且有磁盘缓存.用法示例:还要确保在文件中导入SDWebImage.(如果您使用的是Swift/Carthage,它将导入WebImage

  10. 缓存 – NSURLCache在iOS5上提供不一致的结果,似乎是随机的

    我刚刚花了很长时间在NSURLCache尖叫我,所以我提供了一些建议,希望别人能够避免我的不幸.这一切都足够合理.我的新应用程序项目只针对iOS5及更高版本,所以我认为我可以利用新的NSURLCache实现我所有的Web缓存需求.我需要一个NSURLCache的自定义子类来处理一些特殊的任务,但是这似乎都被API的有力支持.快速阅读文档,我会参加比赛:我认为一个8MB缓存启动是很好的,我会用更大的

随机推荐

  1. Error: Cannot find module ‘node:util‘问题解决

    控制台 安装 Vue-Cli 最后一步出现 Error: Cannot find module 'node:util' 问题解决方案1.问题C:\Windows\System32>cnpm install -g @vue/cli@4.0.3internal/modules/cjs/loader.js:638 throw err; &nbs

  2. yarn的安装和使用(全网最详细)

    一、yarn的简介:Yarn是facebook发布的一款取代npm的包管理工具。二、yarn的特点:速度超快。Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快。超级安全。在执行代码之前,Yarn 会通过算法校验每个安装包的完整性。超级可靠。使用详细、简洁的锁文件格式和明确的安装算法,Yarn 能够保证在不同系统上无差异的工作。三、y

  3. 前端环境 本机可切换node多版本 问题源头是node使用的高版本

    前言投降投降 重头再来 重装环境 也就分分钟的事 偏要折腾 这下好了1天了 还没折腾出来问题的源头是node 使用的高版本 方案那就用 本机可切换多版本最终问题是因为nodejs的版本太高,导致的node-sass不兼容问题,我的node是v16.14.0的版本,项目中用了"node-sass": "^4.7.2"版本,无法匹配当前的node版本根据文章的提

  4. nodejs模块学习之connect解析

    这篇文章主要介绍了nodejs模块学习之connect解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. nodejs npm package.json中文文档

    这篇文章主要介绍了nodejs npm package.json中文文档,本文档中描述的很多行为都受npm-config(7)的影响,需要的朋友可以参考下

  6. 详解koa2学习中使用 async 、await、promise解决异步的问题

    这篇文章主要介绍了详解koa2学习中使用 async 、await、promise解决异步的问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. Node.js编写爬虫的基本思路及抓取百度图片的实例分享

    这篇文章主要介绍了Node.js编写爬虫的基本思路及抓取百度图片的实例分享,其中作者提到了需要特别注意GBK转码的转码问题,需要的朋友可以参考下

  8. CentOS 8.2服务器上安装最新版Node.js的方法

    这篇文章主要介绍了CentOS 8.2服务器上安装最新版Node.js的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. node.js三个步骤实现一个服务器及Express包使用

    这篇文章主要介绍了node.js三个步骤实现一个服务器及Express包使用,文章通过新建一个文件展开全文内容,具有一定的参考价值,需要的小伙伴可以参考一下

  10. node下使用UglifyJS压缩合并JS文件的方法

    下面小编就为大家分享一篇node下使用UglifyJS压缩合并JS文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

返回
顶部