node-express脚手架生成的项目中实现浏览器缓存
前言:
最近在做基于 node-express 的个人站点 朵朵视野 ,在站点发布之后自己在访问测试的过程中发现站点是没有缓存机制的,这样就导致每次访问站点都需要重新去加载资源,很消耗资源以及用户体验也不是很好.
因为站点有上述问题,所以就着手去解决这个问题,解决方法就是通过浏览器缓存来实现。解决过程也是一波三折,最开始想的是通过设置最大过期时间 maxage 来实现,但是做完测试过程中发现通过这种方法添加浏览器缓存之后,当服务重启之后浏览器缓存依旧存在,而且必须通过手动清空缓存才可以使文件更改的内容生效。
设置过期时间 maxage 无法解决问题就只能继续找解决方法,通过了解浏览器缓存机制发现了第二种方法,就是通过 Last-Modified 实现,现将具体的实现过程记录如下。
node-express通过脚手架生成的项目目录结构如下:
bin下的www是项目入口
node_moduls 项目所需模块
public 静态资源,如图片,js,css
routes 路由文件
views 页面文件
app.js 项目需要的中间件等基本配置
package.json 定义项目的基本信息等,包括项目所需要的模块名和版本号
通过设置 maxage 实现浏览器缓存
- app.use(express.static(myStaticPath, {
- maxage: '2h'
- }))
通过 express.static() 来设置浏览器缓存仅仅只是设置了过期时间,不能够保证服务重启之后浏览器缓存失效,实际项目中发现服务重启之后必须要手动清空浏览器缓存之后才能够将更改的文件正确显示,用户体验不好。
通过设置 Last-Modified 实现浏览器缓存
Last-Modified 实现浏览器缓存原理:浏览器第一次向服务端发送请求时,服务端会返回一个带有 Last-Modified: Sat, 02 Dec 2019 09:03:12 GMT 字段的响应头,表明所请求的文件最新修改时间;当浏览器下一次向服务端发送请求时,请求头会带上 If-Modified-Since: Sat, 02 Dec 2019 09:03:18 GMT字段,该字段的值是上一次服务器 Last-Modified 返回的值,服务器接收到请求后会根据 If-Modified-Since 值进行判断,如果该值小于服务器文件的值则返回新的文件,否则就告诉浏览器使用缓存文件。
node-express 生成的代码结构中创建服务的代码被集合在 app.js 中,这样的话我们设置 Last-Modified 就需要在 app.js 中设置。app.js 中有一段处理 404 错误的代码段,我们可以把设置 Last-Modified 集合到这段代码中。
未添加 Last-Modified 代码的 404 错误处理代码段如下:
- app.use(function (req, res. next) {
- var err = new Error('Not Found');
- err.status = 404;
- next(err);
- })
添加 Last-Modified 处理的 404 错误处理代码段如下:
- 1 app.use(function (req, res. next) {
- 2 var pathname = url.parse(req.url).pathname ;
- 3 // 获取文件日期
- 4 fs.stat('.' + pathname, (err, stat) => {
- 5 if(err) {
- 6 var err = new Error('Not Found');
- 7 err.status = 404;
- 8 next(err);
- 9 }else {
- 10 if (req.headers['if-modified-since']) {
- 11 // 浏览器 if-modified-since 字段值
- 12 var oDate = new Date(req.headers['if-modified-since']);
- 13 var time_client = Math.floor(oDate.getTime() / 1000);
- 14 // 服务端文件最新修改时间
- 15 var time_server = Math.floor(stat.mtime.getTime() / 1000);
- 16 if (time_client < time_server) {
- 17 // 浏览器缓存文件的修改时间小于服务端文件修改时间,发送文件
- 18 sendFileToClient();
- 19 }else {
- 20 // 浏览器缓存文件的修改时间等于或大于服务器文件的修改时间
- 21 // 发送 304 状态码,告知浏览器从缓存中读取数据
- 22 res.writeHeader(304);
- 23 res.write('Not Modified');
- 24 res.end();
- 25 }
- 26 }else {
- 27 // 浏览器是第一次请求该文件,不存在 if-modified-since 字段
- 28 // 从服务器端读取文件
- 29 sendFileToClient();
- 30 }
- 31 function sendFileToClient() {
- 32 var rs = fs.createReadStream(`.${pathname}`);
- 33 // 设置请求头 Last-Modified 字段,值为该文件最新修改时间
- 34 res.setHeader('Last-Modified', stat.mtime.toGMTString());
- 35 // 输出
- 36 rs.pipe(res);
- 37 rs.on('error', err => {
- 38 var err = new Error('Not Found');
- 39 err.status = 404;
- 40 next(err);
- 41 });
- 42 }
- 43 }
- 44 })
- 45 })
后话:
通过设置 Last-Modified 根本上解决了浏览器缓存文件更改后无法感知更新的问题,无论是访问速度还是用户体验上都有了很大的提高。
node-express脚手架生成的项目中实现浏览器缓存的更多相关文章
- Node + Express + vue2.0 + Webpack项目实践
技术 Express.Vue.Vue-Router.Vue-Resource.Webpack Vue vue 的组件化思想和 React 很像,一个 vue 组件将 html.css 和 js 都写在 ...
- 【手摸手,带你搭建前后端分离商城系统】02 VUE-CLI 脚手架生成基本项目,axios配置请求、解决跨域问题
[手摸手,带你搭建前后端分离商城系统]02 VUE-CLI 脚手架生成基本项目,axios配置请求.解决跨域问题. 回顾一下上一节我们学习到的内容.已经将一个 usm_admin 后台用户 表的基本增 ...
- vue-cli+webpack在生成的项目中使用bootstrap方法(二)
vue-cli+webpack在生成的项目中使用bootstrap方法(一)中,是通过手动下载bootstrap库,然后手动添加到src/assets中,显然是过程太多. 当然是可以更省力些,可以通过 ...
- 全面解析vue-cli生成的项目中使用其他库(js库、css库)
前言:最近有小伙伴问我,是不是用vue脚手架生成的项目就不能jquery了呢?显然,答案是否定的,必须能用.但是个人建议最好不要用了,用人家vue提供的不好嘛. 一.用vue-cli生成项目 1. v ...
- 解决Ajax中IE浏览器缓存问题
解决Ajax中IE浏览器缓存问题 1.首先,先看一张图.从这张图中我们可以清楚的了解到从请求的发出到解析响应的过程. 2.根据图中的三个节点我们可以使用三种方式解决这个缓存问题(主要是针对ie) 2. ...
- vue-cli+webpack在生成的项目中使用bootstrap
在也个html页面中加入bootstrap是很方便,就是一般的将css和js文件通过Link和Script标签就行. 那么在一个用vue-vli生成的前端项目中如何加入?因为框架不一样了,略微要适应一 ...
- vue-cli+webpack在生成的项目中使用bootstrap的方法
在一个html页面中加入bootstrap是很方便,就是一般的将css和js文件通过Link和Script标签就行.那么在一个用vue-vli生成的前端项目中如何加入?因为框架不一样了,略微要适应一下 ...
- vue-cli+webpack在生成的项目中使用bootstrap方法(一)
在一个html页面中加入bootstrap是很方便,就是一般的将css和js文件通过Link和Script标签就行. 那么在一个用vue-vli生成的前端项目中如何加入?因为框架不一样了,略微要适应一 ...
- nuxt 脚手架创建nuxt项目中不支持es6语法的解决方案
node本身并不支持es6语法,我们通常在vue项目中使用es6语法,是因为,我们使用babel做过处理, 为了让项目支持es6语法,我们必须同时使用babel 去启动我们的程序,所以再启动程序中加 ...
随机推荐
- NodeJS4-8静态资源服务器实战_构建cli工具
Cli(command-line interface),中文是 命令行界面,简单来说就是可以通过命令行快速生成自己的项目模板等功能(比较熟悉的是vue-cli脚手架这些),把上述写的包做成Cli工具. ...
- 基于WCF 的远程数据库服务访问技术
原文出处:http://www.lw80.cn/shuji/jsjlw/13588Htm.Htm摘要:本文介绍了使用WCF 建立和运行面向服务(SOA)的数据库服务的系统结构和技术要素,分析了WCF ...
- go 1.13编译遇到xxx/go.mod malformed record data 问题
背景: 公司在做自己的发布平台,需要自动化编译go 工程,大部分开发使用的都是go 1.12 版本 由于go mod的机制,有很多包需要代理才能进行下载,而自动化编译频繁的进行代理切换就很麻烦. 所以 ...
- 起言-----UE4学习方法
1.bilibili 2.官网教程 3.我觉得以上两个就够了 官方文档链接 https://docs.unrealengine.com/ 官网在线视频链接 https://learn.unrealen ...
- windows环境下Git的安装部署
一.获取安装包 百度搜索“git”,或者访问git官网:https://git-scm.com/,在首页中点击“downloads”进入下载页面 点击“windows”,获取安装包 二.安装部署 双击 ...
- 一起学Vue之样式绑定
在前端开发中,设置元素的 class 列表和内联样式是基本要求.本文主要讲解Vue开发中,样式列表和内联样式的绑定,仅供学习分享使用,如果有不足之处,还请指正. 概述 Vue操作元素的 class 列 ...
- Java 密码加盐
只对密码进行md5加密很容易反推出来,另外两个用户的密码相同时,数据库保存相同的密码,知道一个用户的密码就知道另一个.解决方法是在用户的短密码后面加上一段长字符,再计算 md5,这样反推出原始密码就变 ...
- Apache—伪静态配置和使用
https://jingyan.baidu.com/article/ae97a646a7419bbbfd461df7.html https://blog.csdn.net/weixin_4178205 ...
- Java多线程面试问答
今天,我们将讨论Java 多线程面试问答. 线程是Java面试问题中的热门话题之一.在这里,我从面试的角度列出了大多数重要的Java多线程面试问题,但是您应该对Java线程有足够的知识来处理后续问题. ...
- Oracle11g在虚拟机win7上的详细安装过程(包括win7在虚拟机上的安装)
http://www.imsdn.cn/这个是镜像文件的下载地址,之前下载雨林和深度的VM识别不了. 这个好了之后就可以去这个网址下看安装教程很详细.https://blog.csdn.net/u01 ...