vue网站index.html被微信缓存问题 #
问题描述 #
vue网站index.html被微信缓存,网站发布更新后,微信打开网页显示白屏。
vue项目每次打包输出的js、css等文件名可能不一样(带哈希字符串),发布更新后,缓存的旧版index.html引用的js、css等文件已找不到。
解决方案 #
方案A #
nginx等代理对html文件添加响应头部:
text
location / {
if ($request_filename ~* .*\.html$) {
add_header Cache-Control "must-revalidate";
}
}
也可以配置为下列任一指令:
text
# 禁用缓存。
add_header Cache-Control "no-cache";
# 彻底禁用缓存。注意:add_header必须放在location块中。
add_header Cache-Control "no-store";
# 过期时间设置为epoch元年
expires epoch;
# 过期时间设置为上一秒
expires -1;
Cache-Control响应头部可选值:
- no-cache: 浏览器在使用缓存前需要先验证缓存有效性。
- no-store: 彻底禁止缓存。它要求浏览器和任何中间代理都不应存储任何关于这个请求或响应的信息。
- must-revalidate: 它要求浏览器本地缓存过期后,必须去源服务器进行有效性校验,过期前无需验证。
关于客户端缓存有效性验证:请求时添加 If-Modified-Since 或 If-None-Match 头部询问服务器缓存是否有效,当返回状态码为304时表示缓存有效,此时服务器不会返回内容,客户端应直接使用缓存内容。
方案B #
发布过程,只做新增和更新覆盖操作,不做删除操作。
方案C(可行性?) #
修改vue配置,输出文件名去掉hash部分即可。
配置格式如下:
js
// vue.config.js
module.exports = {
configureWebpack: {
output: {
filename: 'js/[name].[contenthash:8].js',
chunkFilename: 'js/[name].[contenthash:8].js'
}
},
css: {
extract: {
filename: 'css/[name].[contenthash:8].css',
chunkFilename: 'css/[name].[contenthash:8].css'
}
}
}
可以改成:
js
// vue.config.js
module.exports = {
configureWebpack: {
output: {
filename: `js/[name].js?v=[contenthash:8]`,
chunkFilename: `js/[name].js?v=[contenthash:8]`
},
},
css: {
extract: {
filename: `css/[name].css?v=[contenthash:8]`,
chunkFilename: `css/[name].css?v=[contenthash:8]`
}
}
};
[name]
: 每个打包 chunk 或者 entry 的名称。[contenthash:8]
: 基于每个文件内容的hash值生成的唯一字符串,这里的:8意味着只取前8个字符。
图片等其他静态资源怎么办?