我使用
vue-cli
创建了一个应用程序,然后构建了 dist
文件夹用于生产。
该应用程序部署在带有 Flask 后端的
IIS
上并且工作正常。
当我必须进行一些更改并且必须重做部署时,就会出现问题。此后,用户打电话给我,因为应用程序无法工作,但如果我清除 chrome 缓存,应用程序会再次正常工作。
如何解决这个问题?有没有办法在发布新的应用程序版本时自动清除 chrome 缓存?
谢谢
我的 dist 文件夹
部署:在IIS上复制粘贴文件夹dist
如果 dist 文件夹中的文件正确,问题可能出在 axios 缓存中?我也对其余 api 做了一些更改
我遇到了同样的问题,并在运行构建命令之前更改(递增)package.json 中的版本号修复了该问题。
例如,默认情况下版本号设置为
"0.1.0"
package.json 文件:
{
"name": "project-name",
"version": "0.1.1",
"private": true,
...
}
您需要在 js 文件中添加版本查询。这就是浏览器如何知道文件是否已更改并需要下载新版本的方式。
所以类似:
<script src="main.js?v=1.1"></script>
<script src="main.js?v=1.2"></script>
等等...
假设这与 Service Worker/PWA 无关,则可以通过返回前端版本来实现解决方案。
axiosConfig.js
axios.interceptors.response.use(
(resp) => {
let fe_version = resp.headers['fe-version'] || 'default'
if(fe_version !== localStorage.getItem('fe-version') && resp.config.method == 'get'){
localStorage.setItem('fe-version', fe_version)
window.location.reload() // For new version, simply reload on any get
}
return Promise.resolve(resp)
},
)
您还可以确保基于任何类型的唯一性返回
fe-version
,这里我使用了提交 SHA。
完整文章在这里:https://blog.francium.tech/vue-js-cache-not-getting-cleared-in-production-on-deploy-656fcc5a85fe
您无法访问浏览器的缓存,这将是一个巨大的安全漏洞。
要修复此问题,您必须发送一些带有 Flask 响应的标头,告诉浏览器不要缓存您的应用程序。
这是
express.js
的示例,让您了解一下:
setHeaders: function (res, path, stat) {
res.set('Cache-Control', 'no-cache, no-store, must-revalidate') // HTTP 1.1
res.set('Pragma', 'no-cache') // HTTP 1.0
res.set('Expires', '0') // Proxies
}
您可以在此处阅读更多有关缓存的信息。
我通过 webpack.mix.js 文件将哈希添加到应用程序块文件中,添加:
mix.webpackConfig({
output: {
chunkFilename: 'js/[name].js?id=[chunkhash]',
},
})
这会向实际块添加指纹,而不仅仅是 app.js 文件。您还可以通过添加 version(['public/js/app.js']); 向 app.js 文件添加版本名称。在文件末尾,或将 filename: '[name].js?[hash]' 添加到输出块。我完整的 webpack.mix.js:
const mix = require('laravel-mix');
mix.webpackConfig({
output: {
chunkFilename: 'js/main/[name].js?id=[chunkhash]',
}
}).js('resources/js/app.js', 'public/js').vue()
.postCss('resources/css/app.css', 'public/css', [
//
]).version(['public/js/app.js']);
在我使用的 Laravel Blade 文件中
<script src="{{ mix('js/app.js') }}"></script>
使用正确的版本指纹加载 app.js 文件。
将其关闭,它就不再这样做了。
<script src="{{ asset('js/app.js?time=') }}{{ time() }}" defer></script>
<head>
...
<script type="text/javascript" language="javascript">
var timestamp = (new Date()).getTime();
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "<%= BASE_URL %>sample.js?t=" + timestamp;
document.head.appendChild(script);
</script>
...
</head>
Delphin RUKUNDO 提供的获得最多支持的答案对我们来说效果非常好。
vm.$forceUpdate();
组件本身也可能需要一个唯一的密钥:
<my-component :key="unique" />