javascript - 如何让 Angular Universal 和 PWA 协同工作?

标签 javascript angular progressive-web-apps angular-universal angular-service-worker

我有一个 SSR Angular 应用程序,我正在尝试将其转换为 PWA。我希望它为 SEO 和它提供的“快速首次渲染”在服务器端渲染。

PWA 模式在与 SSR 结合使用时可以正常工作,但是一旦加载应用程序,当我们刷新它时,会加载客户端索引 HTML 文件,而不是加载服务器端呈现的页面。

我已经深入研究了 ngsw-worker.js 的代码我看到了这个:

// Next, check if this is a navigation request for a route. Detect circular
// navigations by checking if the request URL is the same as the index URL.
if (req.url !== this.manifest.index && this.isNavigationRequest(req)) {
    // This was a navigation request. Re-enter `handleFetch` with a request for
    // the URL.
    return this.handleFetch(this.adapter.newRequest(this.manifest.index), context);
}

我无法控制这个文件,因为它来自框架并且没有暴露给开发人员。
有没有人为此找到解决方案或解决方法?

最佳答案

旧答案(出于考古目的)
我找到了一个可行的解决方案,navigationUrls ngsw-config.json 的属性(property)包含包含或排除的导航 URL 列表(带有感叹号),如 the documentation 中所述.
然后我像这样配置它:

"navigationUrls": [
    "!/**"
]
这样,所有 URL 都不会重定向到 index.html。当应用程序第一次被请求(或刷新)时,无论 URL 是什么,服务器端呈现的应用程序都会发挥作用。
更进一步,由 service worker 管理的三种 URL 是:
  • 非导航 URL:由 service worker 缓存并列在生成的 ngsw.json 中的静态文件带有相应哈希值的文件
  • 导航 URL:重定向到 index.html默认情况下,如果 "!/**" 则转发到服务器配置使用
  • GET对后端的请求:转发到后端

  • 为了区分GET XMLHttpRequest从导航请求中,服务 worker 使用 Request.mode属性(property)和Accept包含 text/html 的 header 导航时和 application/json, text/plain, */*请求后端时。
    编辑:这实际上不是一个好习惯,原因有两个:
  • 根据网络质量,不保证服务器端版本的渲染速度会比缓存的浏览器版本快
  • 它打破了“后台更新”机制。事实上,服务器端呈现的应用程序将始终引用最新版本的 JavaScript 文件

  • 有关这方面的更多详细信息,请查看 Angular 团队成员对我的功能请求的回答:https://github.com/angular/angular/issues/30861
    最新答案 (v11.0.0)
    Angular 现在有一个 navigationRequestStrategy 允许优先考虑服务器导航请求的选项。更新日志的摘录:

    service-worker: add the option to prefer network for navigation requests (#38565) (a206852), closes #38194


    要明智地使用!此警告出现在文档中:

    The freshness strategy usually results in more requests sent to the server, which can increase response latency. It is recommended that you use the default performance strategy whenever possible.

    关于javascript - 如何让 Angular Universal 和 PWA 协同工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56383569/

    相关文章:

    angular - 运行 Angular 项目时出错

    flask - 如何使 Flask Heroku 应用程序成为渐进式 Web 应用程序 (pwa)

    javascript - 页面加载后如何加载多个脚本?

    javascript - 使用自定义端点扩展现有 API

    javascript - 使用 CSS/Js 的文本动画无法正常工作

    ios - PWA 应用程序在 iOS 进入后台后每次都会初始化

    android - PWA 在后台播放媒体

    javascript - 在父级之外显示子 div,即使它们的标记在 jquery 中

    javascript - 如何通过嵌套的 ng-containers 和 ng-templates 传递数据?

    javascript - 遍历字符串中的每个字母并检查它是否是分隔符