如何在发布新的Vue应用程序版本时强制清除Chrome中的缓存

45

我使用 vue-cli 创建了一个应用程序,然后构建了用于生产的 dist 文件夹。

该应用程序在带有 Flask 后端的 IIS 上部署,并且工作正常。

当我需要进行一些更改并重新部署时,问题就出现了。之后用户给我打电话说应用程序无法工作,但是如果我清除 Chrome 缓存,应用程序会再次正常工作。

我该如何解决这个问题?是否有一种方法可以在发布新应用程序版本时自动清除 Chrome 缓存?

谢谢

我的 dist 文件夹

进入图像描述

部署:将 dist 文件夹复制并粘贴到 IIS 上

如果 dist 文件夹中的文件正确,也许问题在 axios 缓存中?我还对 REST API 进行了一些更改。


你用什么来构建你的应用程序? - bonusrk
在项目文件夹中运行npm run build命令 - nickb84
你找到任何解决方案了吗,@nickb84? - Sachitha Hirushan
10个回答

44

我曾经也遇到过同样的问题,通过在运行构建命令之前更改(增加)package.json中的版本号来解决它。

例如,默认情况下版本号设置为"0.1.0"

package.json文件:

{
  "name": "project-name",
  "version": "0.1.1",
  "private": true,
  ...
}

4
这是强制更新缓存的更好方法。 - Ish
运行 npm run build 后,只需更改 package.json 文件,无需提交到 Git,你知道为什么吗?这真的与命令 npm run build 集成了吗?我已经从版本 0.1.1 推送了我的 dist,然后将其更改为 1.1.1,然后运行 npm run build,但不需要提交或推送。我认为我们需要先运行 npm install,对吗? - Yogi Arif Widodo

28

如果您使用vue-cli,那么它具有用于构建dist的内置webpack配置。实际上,它会将哈希名称添加到输出文件中。 但是,如果不知何故删除了此配置,可以像下面这样将其添加回webpack配置文件中:

  output: {
    filename: '[name].[hash].bundle.js'
  }

你的应用程序将会像这样: enter image description here

而且更好的是,你不需要处理所有这些东西如何添加到HTML中,因为Webpack会替你解决这个问题。


6
你的解决方案似乎有效。创建了 'vue.config.js' 并编写了以下内容:module.exports = { configureWebpack: { output: { filename: '[name].[hash].bundle.js' } } }默认情况下,Vue CLI 确实启用了哈希功能:https://cli.vuejs.org/config/#filenamehashing - akauppi
2
这只会更改我的app.bundle.js文件的名称,而不会更改像/js/0.js这样的其他文件。 - Stefan Höltker
由于块名称设置放置在webpack设置的其他参数中,取决于您用于拆分块的解决方案(插件),因此需要注意。 - bonusrk
这对我来说有点用。唯一的问题是它不会每次更新哈希值。我们如何在每次运行构建时更新哈希值? - waseber
它有不同的哈希构建策略,你可以在方括号内定义名称。例如,你可以将[hash]更改为[contenthash],它将基于上下文构建哈希名称,并在内容更改时重新构建。(但当然,对于相同的内容,哈希值将是相同的) - bonusrk

3
假设这与服务工作者 / 渐进式网络应用程序无关,则可以通过返回前端版本来实现解决方案。
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

3

您需要在js文件中添加一个版本查询。这样浏览器就能知道该文件是否已更改并需要下载新版本。

可以像下面这样:

<script src="main.js?v=1.1"></script>

<script src="main.js?v=1.2"></script>

etc...


但是在哪里?在index.html文件中吗? - nickb84
在加载您的脚本的HTML页面中,确保有版本标签。通常webpack会自动添加此版本标签。如果您无法添加,请与我们分享您的配置文件,以便我们查看发生了什么。 - T. Short

1

这是一篇较旧的文章,但由于我在网上找不到解决此问题的方案,因此我将在此发布,以防其他人可能会发现它有用。

我通过在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 文件。


1

您无法访问浏览器的缓存,否则将会存在严重的安全漏洞。

为了解决这个问题,您必须在 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
  }

您可以在此处阅读更多关于缓存的内容。


0
将以下脚本添加到 publc/index.html 中:
<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>

0
对我来说,答案是在我的DNS提供商级别上进行缓存。 基本上,我正在使用Cloudflare DNS代理,他们正在缓存网站,因此在开发模式下,我没有获得代码更新。 我不得不多次清除缓存才能使任何内容更改。 我必须等待相当长的时间才能更新任何内容。
关闭它后,它就停止这样做了。

0

我想要建议的方法是:

<script src="{{ asset('js/app.js?time=') }}{{ time() }}" defer></script>


-9

你能试一下吗?

vm.$forceUpdate();

同时,组件本身可能需要一个唯一的键:

<my-component :key="unique" />

4
这是对另一个问题的很好的回答,确实如此。 - Exis Zhang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接