【问题标题】:Angular 2/ CLI Refresh Browser after updateAngular 2/ CLI 更新后刷新浏览器
【发布时间】:2020-09-07 01:12:24
【问题描述】:

使用 Angular 5.2.2 和 Angular CLI 1.7.0。在ng build --prod 和更新服务器之后。客户端仍在使用旧版本,无法看到更新版本。即使是散列的捆绑包。有没有一种方法可以自动更新到最新版本,而无需让客户端单击浏览器上的刷新按钮(基本上是强制刷新)?提前谢谢你。

Angular CLI: 1.7.0
Node: 8.9.4
OS: darwin x64
Angular: 5.2.3
... animations, common, compiler, compiler-cli, core, forms
... http, platform-browser, platform-browser-dynamic
... platform-server, router, service-worker

@angular/cdk: 5.2.0
@angular/cli: 1.7.0
@angular/material: 5.2.0
@angular-devkit/build-optimizer: 0.3.1
@angular-devkit/core: 0.3.1
@angular-devkit/schematics: 0.3.1
@ngtools/json-schema: 1.2.0
@ngtools/webpack: 1.10.0
@schematics/angular: 0.3.1
@schematics/package-update: 0.3.1
typescript: 2.7.1
webpack: 3.11.0

【问题讨论】:

  • 散列包用于破坏浏览器缓存。如果它们甚至无法正常工作,则您必须有某种其他类型的缓存层导致了这种情况。此外,在不重新加载浏览器的情况下即时更新 UI 确实不是一件容易的事......我能想到的唯一可能的方法是有一个轮询器来检查端点以及该端点何时返回正确的响应(如 @ 987654323@ 或其他东西),然后您可以使用要显示给客户的新 index.html 执行 document.write(...)
  • - 你用来构建哈希包的命令是什么?
  • @RagavanRajan 使用 angular-cli ng build --prod --stats-json --base-href=/mywebapp/ --output-path=../serverfolder/mywebapp

标签: angular angular-cli


【解决方案1】:

假设如果你有很多环境,在所有环境中添加 oh 标志

- ng build --test --no-progress -oh all

并在生产中明确添加它

您必须使用输出哈希选项来生成文件

所以命令将是

ng build --prod --stats-jason --base-href=/mywebapp/ --output-path=../serverfolder/mywebapp --output-hashing all

或使用别名 (-oh)

ng build --prod --stats-jason --base-href=/mywebapp/ --output-path=../serverfolder/mywebapp -oh all

然后使用dist 文件夹中的文件并检查它在所有文件中的唯一哈希值,然后托管它,拜托。 希望对你有帮助

【讨论】:

  • 哈希是唯一的,当我执行ng build --prod 时,默认情况下执行 --prod 我相信 angular-cli 适用 --output-hashing=all。 github.com/angular/angular-cli/wiki/…
  • 同意 wiki 链接。我的假设是当您拥有多个环境时,如果未将 -oh all 标志添加到所有环境,那么您将面临这个问题。所以尝试在所有环境中添加-oh 标志并尝试一下
  • 我添加了 output-hashing=all。不幸的是,我得到了相同的结果。客户端保持旧缓存版本,浏览器不更新。
  • 在 Angular V7-输出散列中,包优化包含在 angular.json 文件中。配置 > 生产部分。希望对你有帮助
【解决方案2】:

几件事:

  1. 确保正在创建的包具有唯一的哈希值。
  2. 如果它们有唯一的哈希,请确保没有二级缓存层,因为唯一的哈希会破坏浏览器的缓存,因此您的情况很不寻常。

现在,如果您希望客户端在不重新加载浏览器的情况下接收新的更新包,那么您可以实现的一种方法(我目前能想到的唯一方法)是连接轮询器或套接字或某种连接到您的服务器,当它收到正确的响应/消息时,您可以在响应中使用新的index.html 执行document.write(...) 之类的操作。

这是一个伪代码示例:

setInterval(() => {
    http.get('/needs-update').subscribe((yes: boolean) => {
        if (yes) {
            http.get('/new-bundle').subscribe((newBundle: string) => {
                document.write(newBundle);
            });
        }
    });
}, 60000);

每分钟,它都会轮询是否需要一个新的捆绑包。如果是这样,它将获得新的捆绑包。

您可以权衡document.write() 方法的成本/收益,但我认为这可以让您大致了解投票方法。

【讨论】:

  • 感谢您的快速回复。不知道为什么浏览器不更新/刷新但哈希是唯一的。另外,在我这边更正。我的意思是说我的目标是更新/上传我的代码,在客户端,他们应该能够看到反映的更改,而无需单击重新加载/刷新按钮或弹出带有单击按钮的弹出窗口来重新加载/刷新您的浏览器。
  • 我明白了。我给出的示例代码没有向用户显示任何提示。这是一个自动后台进程,将在不重新加载页面的情况下更新用户包。阅读代码,你会看到:)
  • 好吧,让我试一试。
【解决方案3】:

是的,基本思想是服务器根据文件加载路由,但您的整个 Angular 应用程序在 index.html 上运行,它告诉浏览器要显示哪个路由,因此使用 htaccess 您几乎可以将所有服务器传入流量路由到索引.html 一切运行顺利:) 这是我正在使用的 .htaccess:

RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]

【讨论】:

    猜你喜欢
    • 2017-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 2015-02-18
    • 1970-01-01
    • 2014-08-10
    相关资源
    最近更新 更多