每次打包更新版本上传到服务器上,会偶尔出现代码没有更新还是旧代码的逻辑,这就代表浏览器存在缓存的问题了。
有以下几种方案:
1、修改根目录index.html
在 head
里面添加下面代码
<!--清除浏览器中的缓存 -->
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
这种会让所有的css/js
资源重新加载
2、配置nginx
不缓存 html
vue
默认配置,打包后css
和js
的名字后面都加了哈希值,不会有缓存问题。但是index.html
在服务器端可能是有缓存的,需要在服务器配置不让缓存index.html
location = /index.html {
add_header Cache-Control "no-cache, no-store";
}
no-cache
浏览器会缓存,但刷新页面或者重新打开时 会请求服务器,服务器可以响应304
,如果文件有改动就会响应200
no-store
浏览器不缓存,刷新页面需要重新下载页面
3、打包的文件路径添加时间戳
vue-cli2
webpack .prod.conf.js
下修改output
//定义一个变量获取当前时间戳
const Timestamp = new Date().getTime();
//output模块将时间戳加入到输出的文件名里
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].'+Timestamp+'js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].'+Timestamp+'js')
}
//css文件名加时间戳
new ExtractTextPlugin({
filename: utils.assetsPath(`css/[name].[contenthash].${Timestamp}.css`),
allChunks: true,
}),
vue-cli3
vue.config.js
下修改/添加output
const Version = new Date().getTime()
module.exports = {
css: {
loaderOptions: {
sass: {
data: `@import "@/components/themes/_handle.scss";`
}
},
// 是否使用css分离插件 ExtractTextPlugin
extract: {
// 修改打包后css文件名 // css打包文件,添加时间戳
filename: `static/css/[name].${Version}.css`, // 此处static/css/xxx 目录根据自己打包情况来定,我使用的就没有static一层,所以直接去掉static即可。根据自己项目决定
chunkFilename: `static/css/[name].${Version}.css`
}
},
configureWebpack: {
output: { // 输出重构 打包编译后的 文件名称 【模块名称.版本号.时间戳】
// filename: utils.assetsPath('js/[name].[chunkhash].'+Version+'js'),
// chunkFilename: utils.assetsPath('js/[id].[chunkhash].'+Version+'js')
filename: `static/js/[name].${Version}.js`, // js打包文件,添加时间戳
chunkFilename: `static/js/[name].${Version}.js`
}
},
chainWebpack(config) {
// img的文件名修改 // img打包文件,添加时间戳
config.module
.rule('images')
.use('url-loader')
.tap(options => {
options.name = `static/img/[name].${Version}.[ext]`
options.fallback = {
loader: 'file-loader',
options: {
name: `static/img/[name].${Version}.[ext]`
}
}
return options
})
}
}
对于以上的几种方案,普通的缓存问题都可以解决,如果你已经通过上面的方案解决的问题,下面的内容就不需要再看了😄😄😄。
但是最近有遇到微信公众号菜单里面配置网页,微信公众号里网页的缓存很深很深,特别是在iOS手机上,上面几种方法均不能解决。
我找到下面几种解决方案,但是未尝试,如果有人遇到,尝试下面的方案看看是否可以解决公众号里缓存问题。
方案1:配置nginx
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|js)$ {
root /mnt/dat1/test/tes-app;
#### kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
}
方案2:改变web访问url
举例:原访问路径是 https://www.xxx.com/policy/#/abc.vue
,policy
是项目名称,前端项目放在服务器data/hdwork-h5
目录下。
在#
前面加版本号就变成:https://www.xxx.com/policy/123/#/abc.vue
,123
是版本号的举例,这个可以自己定,是个数字就可以,这种做法简单,只需要nginx
再多加一个匹配数字的配置就可以。以下是nginx
项目的配置参考,具体以自己项目定义。这里只给出了匹配/policy/\d+ 匹配数字
的案例,不加数字的/policy
就是原逻辑。
这样 加版本号https://www.xxx.com/policy/{版本号}/#/abc.vue
和 不加版本号https://www.xxx.com/policy/#/abc.vue
,这两种方式都是可以正常访问的
原理就是 当我们请求带版本号的请求路径https://www.xxx.com/policy/123/#/abc.vue
时,会自动重写成 正常的访问路径https://www.xxx.com/policy/#/abc.vue
,这样就达到了修改请求路径从而让微信浏览器以为这是一个新的路径,就不会有缓存的情况。
但是这样的话,需要每次发完版本,在公众号后台里面修改配置的网页url
方案3:刷新页面
1.就是在每次进入的时候,刷新页面,刷新就会获取最新版本的网页
2.或者是定义一个版本号,本地存一个本地的版本号,通过接口获取当前最新的版本号,如果版本不一致就进行刷新页面。
刷新页面这种方案,可能会出现页面闪动一下,体验不好的情况
other:
hash
以前使用 JQuery
开发前端页面的时候,页面中引用的资源文件如js、css
等,一般尾部加一个 t=[时间戳] 参数,用于防止修改不生效。现在工程化开发,使用 Webpack
编译,打包的资源文件路径里自动带有一串随机字符串,称为 hash
:
<link href=/static/css/chunk-vendors.d637be65.css rel=preload as=style>
d637be65
即是hash
。每次 build
都会生成不同的 hash
,所以每次编译部署,都不会有缓存问题。
这个 hash
是如何生成的?它的生成机制是什么?
一共有三种 hash
Webpack 打包后的资源按大小分有三类,从小到大排列:
module,即模块,每个引入的文件就是一个module,常言模块化,是开发中的物理最小代码单位
chunk, N 个模块打包在一起形成的的一个文件(如果 chunk 有 split,则每个分开的文件都是一个独立的 chunk)
bundle,一次工程编译打包的最终产物,有可能就是 chunk,也有可能包含多个chunk的综合体
这三类资源都可以生成 hash,粒度从低到高依次为:
hash,根据每次编译的内容计算所得,不是针对每个具体文件的,每次编译都会有一个 hash
chunkhash,入口级别的 hash,如果入口文件有改动,则从该入口打包引入的所有文件的hash都会变化,主要指同一个入口的js和css文件。
contenthash,文件级别的 hash,只有文件的内容变了hash才会变
参考文档:
浅谈微信页面入口文件被缓存解决方案
微信小程序webview清除缓存、微信公众号h5清除缓存、页面白屏、空白、不刷新问题