nginx 发布前端资源的缓存方案
nginx 发布前端资源的缓存方案
前言
对于前端开发者来说,最头疼的事情莫过于。当你兴冲冲的给项目打包以后,上传到 nginx 等静态资源服务器发布以后,自己本地验证没问题,以为万事大吉,结果测试人员、用户反馈系统没更新,让你顿时感觉如同吃了苍蝇般难受。
没办法,作为一个专业的开发人员,用户反馈程序出问题,第一时间就要找到问题出现的原因。
于是你开始进行检查确认工作,先是打开浏览器访问系统发现没问题,确实是更新以后的版本。然后你开始对自己更新的过程产生了怀疑,上服务器,检查一下更新以后的资源文件,再三的详细比对,发现确实没问题后,你忽然恍然大悟,原来代码确实没问题,有问题的是浏览器缓存。
解决问题思路
前端打包后的文件,其实就是一些静态资源,我们一般情况下,是直接放在静态资源服务器提供服务的。
一般,解决发布资源缓存这个问题,有几种思路:
1. 浏览器设置每次都重新下载页面的所有的资源。
这个方案有个优点,每次拿到的资源都是重新拉去的最新的资源,所以不存在会缓存的问题。
但是这个方案的缺点非常明显,它直接让缓存失去了自身的意义。没有缓存,增加了服务器的负担,对服务器不太友好,同时也让用户使用网页的体验降低了。
而且,默认情况下,没有浏览器会这么设置。如果需要用这个方式,就需要引导用户这么设置,同时也对用户要求太高。
所以这个方案,不用考虑,直接就可以 pass 掉了。
2. 在静态资源服务器上配置,强制不让浏览器进行缓存。
常见的静态资源服务器,像 nginx、apache 等,确实可以配置让客户端永远不缓存静态资源。
虽然与第一个方案相比,它存在一些优点,比如不需要引导用户对浏览器进行配置。
但是弊病和第一种思路一样,对用户和服务器都极其不友好,所以这个方案也可以被 pass 掉了。
3. 最好的解决方案
其实有一种比较好的解决方案,需要前端和静态资源服务器配合起来达到。
前端资源其实分为几类:
- 内容会变化,但是文件名不会变,用户也只能通过某个路径访问到,最典型的就是页面入口的
index.html
文件 - 内容会变化,文件名也可以变化,比如每次打包生成的 js文件、css 文件、图片资源等
- 内容不会变化,文件名也不会变化,比如直接在 html 中引入的第三方包
针对这几种不同的解决方案,可以针对性的作优化。
第一类,可以采用 Etag 的缓存策略。
如果没了解过这个名词的童鞋,可以 mdn 上了解下相关知识:ETag - HTTP | MDN。
简而言之,如果采取了 Etag 策略,那么每次请求某个资源的时候,服务器会在响的的请求头里返回 Etag 标签:
下次,如果再请求同样的资源的时候,浏览器就会在请求头里带上这个 Etag,让服务器进行对比,如果 Etag 能够匹配上,就返回 304,浏览器就明白,不用重新下载资源,直接用本地缓存就行;否则浏览器会返回200,并返回完整的请求资源。
比如,想要在 nginx 中配置 etag,可以参考下面的链接:
Module ngx_http_core_module
直接这样配置即可,同时要在 header 中加上 cache control 控制,让浏览器对 html 文件应用 no-cache
规则。
location ~ .*\.(?:htm|html)$ {...add_header Cache-Control "no-cache";etag on;...
}
不了解 cache-control 的童鞋,可以参考下 mdn 的文档:
Cache-Control - HTTP | MDN
这样配置了以后,对于所有的 html 文件,就达到了当文件没更新的时候,返回 304,当文件更新了,自动拉取最新的资源的目的。
第二类,直接采用强制浏览器缓存的方法。
对于第二类资源,我们可以通过添加 hash 的方式保证,即使前端版本更新了,文件名也不一样,那么我们就不需要像第一种方式一样,通过 Etag 方式去缓存了。
因为即使是 Etag 策略,其实也是会消耗请求资源的。对于这种发布了就不会更改的内容,直接可以通知浏览器长期缓存即可。
想达到这种效果,直接通过配置 cache control header 即可。
location ~ .*\.(?:js|css|jpg|jpeg|gif|png)$ {...add_header Cache-Control "public, max-age=31536000";add_header Last-Modified "";etag off;...
}
直接配置对于第二类资源,关闭 Etag,同时设置强制缓存,同时设置上一年的缓存期。
这样设置了以后,当浏览器再次请求该资源时候,会查看浏览器之前缓存的该资源是否还在有效期以内,如果在,便会直接应用该资源,不会向浏览器再次发起请求了;否则,会重新发起请求,请求该资源。
第三类资源的解决方案,其实跟第二类一样,通过添加 hash 值或者 timeStamp,用以区分资源,达到每次更新版本后,请求的资源不一致。
对于这两类资源的处理,在 nginx 上的配置,也并无差别,可以等同对待。
对于前端来说,就比较麻烦一些。
下面列举一些,在常用的前端框架的脚手架中,该如何配置,以达到自动添加 timeStamp 的效果吧。
- create-react-app
在 react 这个官方脚手架中,支持从环境变量传值: Adding Custom Environment Variables | Create React App
所以,我们直接在模板中,替换调传入的值即可。
/** .env 文件 */
REACT_APP_WEBSITE_NAME=测试标题
REACT_APP_TIMESTAMP=1639814656911
/** html 模板文件,通过传值,替换掉模板中的内容 */
<title>%REACT_APP_WEBSITE_NAME%</title>
<script src="%PUBLIC_URL%/config.js?timeStamp=%REACT_APP_TIMESTAMP%"></script>
- vue-cli
在 vue 脚手架中,可以通过重载 webpack 配置,来设置变量。
/*** @type {import('@vue/cli-service').ProjectOptions}*/
module.exports = {chainWebpack: (config) => {config.plugin('html').tap((args) => {args[0].timeStamp = Date.now();return args;});},
};
然后通过在 index.html 模板中,采用 lodash template 的方式,应用变量。
<script src="<%= BASE_URL %>config.js?timeStamp=<%= htmlWebpackPlugin.options.timeStamp %>"></script>
详细用法可以参考官方文档:HTML and Static Assets | Vue CLI
后记
其实对于同一个问题,往往会有多种不同的解决方案。有时候多研究一下,多思考一下,综合考量,就可以找出一种比较好的解决方案。
nginx 发布前端资源的缓存方案相关推荐
- Nginx做前端代理时缓存与否的性能差别
Nginx做前端代理,后端两台apache upstream webservers {------------------定义在http段server 172.16.20.31 ;server 172 ...
- ngnix mysql 缓存清除_利用Proxy Cache使Nginx对静态资源进行缓存
前言 Nginx是高性能的HTTP服务器,通过Proxy Cache可以使其对静态资源进行缓存.其原理就是把静态资源按照一定的规则存在本地硬盘,并且会在内存中缓存常用的资源,从而加快静态资源的响应. ...
- nginx配置静态资源,重新发布后,浏览器缓存导致异常原因和解决
原因: nginx作为静态资源服务器,重新构建后发生浏览器页面直接取缓存中的js等文件名,但是由于服务器中文件已经被替换导致出现异常. 浏览器在下次请求这个资源的时候不会将请求发向后端,而是直接从缓存 ...
- win10 nginx部署前端项目(静态资源服务器和HTML)
win10 nginx部署前端项目(静态资源服务器和HTML) niginx的安装和启停操作参照博客:https://blog.csdn.net/qq_26666947/article/details ...
- 基于微前端qiankun的多页签缓存方案实践
作者:vivo 互联网前端团队- Tang Xiao 本文梳理了基于阿里开源微前端框架qiankun,实现多页签及子应用缓存的方案,同时还类比了多个不同方案之间的区别及优劣势,为使用微前端进行多页签开 ...
- 使用 Nginx 管理你的前端资源
前言 在前端项目开发中,我们可以启动 devserver 管理静态资源服务,但是发布线上后要保证稳定,一般会选择一个高效能 + 稳定的静态服务器来管理前端资源. 作为前端工程化的关键一环节,这一篇我们 ...
- 前端网页发布到nginx_通过nginx部署前端代码实现前后端分离
实现前后端分离,可以让前后端独立开发.独立部署.独立单测,双方通过JSON进行数据交互. 对于前端开发人员来说,不用每次调试都需要启动或配置Java/Tomcat运行环境:对于后端开发人员来说 ,也不 ...
- nginx 部署前端项目,不缓存html文件,项目发版后,不用手动刷新页面
nginx 部署前端项目,不缓存html文件,项目发版后,不用手动刷新页面 location / {expires 1h;root /home/test/vue/dist/;index index.h ...
- 前端访问nginx发布的视频文件,实现在线播放
文章目录 简介 依赖插件 nginx 配置 前端配置 css文件配置 html页面脚本 js脚本 实现效果 简介 主要是为了解决观看本地的视频文件,有时也需要在服务器上发布预览视频文件,所以就做了这么 ...
最新文章
- 未处理的异常导致基于 ASP.NET 的应用程序意外退出
- SpringMVC如何实现aop
- Python学习笔记(八)—使用正则获取网页中所需要的信息。
- python【数据结构与算法】判断对称二叉树
- 1319. 连通网络的操作次数
- 行内块元素(HTML、CSS)
- (Spring Cloud微服务实战-书中之坑)spring cloud zuul统一处理业务异常,并且需要响应状态为200...
- 今天起改用mac的marsedit写博
- 【C语言】10-字符和字符串常用处理函数
- win10删除自定义的背景图片历史记录
- Linux上的arping命令介绍
- javascript获取浏览器窗口大小 获取屏幕,浏览器,网页高度宽度
- Flash游戏开发技术分析(上)
- 第149篇 笔记-web3
- ChatGPT宝藏插件丨装上之后,上网、语音聊天、一键分享对话……简直让你爽到起飞!
- 梯度下降算法和牛顿算法原理以及使用python用梯度下降和最小二乘算法求回归系数
- 快速理解数据库函数依赖(平凡函数依赖、非平凡函数依赖、完全函数依赖、部分函数依赖、传递依赖)
- python_爬虫 16 Scrapy框架之(二)快速入门
- IntelliJ IDEA汉化,IntelliJ IDEA安装中文语言包。IntelliJ IDEA 2020.1正式发布,支持中文啦。
- 爬虫期末考试笔记(填空题)