广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >如何利用node实现静态文件缓存详解
  • 931
分享到

如何利用node实现静态文件缓存详解

2024-04-02 19:04:59 931人浏览 八月长安
摘要

目录缓存缓存位置分类缓存设置headernode实现静态文件缓存强缓存思路代码实现效果展示协商缓存思路代码实现效果展示总结缓存 浏览器缓存(Brower Caching)是浏览器对

缓存

浏览器缓存(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静态文件缓存内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 如何利用node实现静态文件缓存详解

本文链接: https://www.lsjlt.com/news/130086.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何利用node实现静态文件缓存详解
    目录缓存缓存位置分类缓存设置headernode实现静态文件缓存强缓存思路代码实现效果展示协商缓存思路代码实现效果展示总结缓存 浏览器缓存(Brower Caching)是浏览器对...
    99+
    2022-11-12
  • 详解如何利用jasypt实现配置文件加密
    目录引入依赖生效作用域应用工具类配置属性一览进阶Jasypt (Java Simplified Encryption) 是一个 java 库,它允许开发人员以最小的成本将基本的加密功...
    99+
    2022-11-13
  • 如何使用Go语言实现路由的静态文件服务
    如何使用Go语言实现路由的静态文件服务概述:在Web开发中,静态文件服务是非常常见且重要的功能。它通常用于提供网站的静态资源,例如HTML、CSS、JavaScript、图像等。本文将介绍如何使用Go语言实现一个简单的路由的静态文件服务,并...
    99+
    2023-12-17
    Go语言 路由 静态文件服务
  • 如何利用Redis实现分布式文件存储
    如何利用Redis实现分布式文件存储在分布式系统中,大规模的文件存储是一个常见的需求。Redis作为一个高性能的缓存和存储系统,具有快速、可靠和可扩展的特点,非常适合用来实现分布式文件存储。本文将介绍如何利用Redis实现分布式文件存储,并...
    99+
    2023-11-07
    分布式 redis 文件存储
  • 利用Java如何实现解析Excel文件并存入数据库中
    利用Java如何实现解析Excel文件并存入数据库中?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1.web.xml中的配置文件web.xml中的配置文件就按照这种方式写,...
    99+
    2023-05-31
    java excel ava
  • 图文详解如何利用PyTorch实现图像识别
    目录使用torchvision库的datasets类加载常用的数据集或自定义数据集使用torchvision库进行数据增强和变换,自定义自己的图像分类数据集并使用torchvisio...
    99+
    2023-05-14
    pytorch图像识别 pytorch 图像 pytorch中文手册
  • 详解利用C语言如何实现简单的内存池
    前言 在编程过程中,尤其是对于C语言开发者,其实编程就是在使用内存,不停地变化内存中的数据。当我们想开辟一片新的内存使用时,就会使用malloc实现。但是通过查阅很多资料,发现频繁的...
    99+
    2022-11-12
  • 如何使用Java缓存HTTP请求日志?详解实现步骤
    当今互联网时代,HTTP请求日志已经成为了系统监控和性能优化的重要指标之一。为了更好地跟踪和分析系统运行状态,我们需要对HTTP请求日志进行缓存处理。本文将详细介绍如何使用Java缓存HTTP请求日志,包括实现步骤和演示代码。 一、缓存HT...
    99+
    2023-07-24
    http 日志 缓存
  • 详解如何使用Python实现删除重复文件
    目录Python自动化办公之删除重复文件思路介绍源码解说知识拓展Python自动化办公之删除重复文件 思路介绍 两层判断: 1.先判断文件大小是否为相同,大小不同则不是重复文件,予以...
    99+
    2022-11-11
  • 利用java读取超大文件时出现内存溢出如何解决
    利用java读取超大文件时出现内存溢出如何解决?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1. 传统方式:在内存中读取文件内容读取文件行的标准方式是在内存中读...
    99+
    2023-05-31
    java ava
  • React如何利用Antd的Form组件实现表单功能详解
    一、构造组件 1、表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等。 这里先引用了封装的表单域 <Form.Item /> 2、使用For...
    99+
    2022-11-12
  • 详解如何使用Nginx搭建文件服务器及实现文件服务
    前言 公司最近有做文件服务器的需求,并且使用到了Nginx做负载均衡服务器,顺水推舟,就想着顺便用作文件服务器算了,实际上它也非常适合。 Nginx是一种轻巧、高效的Web服务器,用作文件服务器非常合适。但是如果需要一些高级功能,如FTP远...
    99+
    2023-09-08
    nginx java springboot 服务器 linux
  • Excel文件利用Poi进行读取时出现内存溢出如何解决
    这篇文章给大家介绍Excel文件利用Poi进行读取时出现内存溢出如何解决,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1.dump内存文件liunx使用如下命令:./jmap -dump:format=b,file=h...
    99+
    2023-05-31
    poi excel
  • 如何利用rman copy的方法实现存储上裸设备数据文件的迁移ITPUB
    小编给大家分享一下如何利用rman copy的方法实现存储上裸设备数据文件的迁移ITPUB,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧! 利用rman copy的方法实现存储上裸设备数据...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作