【问题标题】:Angular 7 - Service Worker PWA + SSR not working on serverAngular 7 - Service Worker PWA + SSR 在服务器上不起作用
【发布时间】:2019-07-05 02:52:21
【问题描述】:

我正在努力让我的服务器端渲染和 Service Worker 在服务器端进行协作。

有关本地主机的信息 -> 工作

这是按预期工作的。服务人员工作并在每次更新时更新我的​​应用程序。而且; curl localhost:8082 发回我的信息。

我使用以下命令启动我的应用程序:npm run ssr

 "ssr": "npm run build:ssr && npm run serve:ssr",
 "build:ssr": "npm run build:client-and-server-bundles",
 "serve:ssr": "node dist/server.js",
 "build:client-and-server-bundles": "ng build --prod && npm run webpack:server",
 "webpack:server": "webpack --config webpack.server.config.js --progress --colors"

有关生产的信息: -> 不工作

网站通过 HTTPS:https://airdropers.io 网站进程在关闭端口上运行,并且 HAPROXY 将流量从 443 重定向到网络服务器的端口

Web 服务器日志上可见的问题:无法订阅通知 错误:此浏览器禁用或不支持 Service Worker

额外信息:

本地和生产上的节点js是一样的:v9.0.0 我使用以下过程构建生产:

  1. git 拉
  2. npm run build:ssr
  3. pm2 启动 dist/server.js

2019 年 2 月 23 日更新

我现在有了更深的了解。 我的问题是我使用诸如“node dist/server.js”之类的节点命令启动我的 SSR/PWA 服务器。

据我了解,“node dist/server.js”不适用于 Service Worker (PWA) 我引用 (https://angular.io/guide/service-worker-getting-started)

由于 ng serve 不适用于服务工作者,因此您必须使用 单独的 HTTP 服务器在本地测试您的项目。你可以使用任何 HTTP 服务器。下面的示例使用来自 npm 的 http-server 包。 减少冲突的可能性,避免服务陈旧 内容,在专用端口上测试并禁用缓存。

我无法使用http-server dist/browser 启动,因为我会失去 SSR 功能。

如何启动我的 PWA/SSR 服务器? 我应该使用什么命令?
我要做什么构建?

2019 年 2 月 24 日更新

正如@Gökhan Kurt 所提到的,服务人员无法与我的 SSR 服务器正常工作。 我需要用于 SEO 的 SSR,我需要用于浏览器推送通知的服务人员。 我有什么解决方案来处理浏览器用户推送通知? One Signals 等第三方库?


欢迎任何想法建议来帮助我完成这项工作。 谢谢你的支持, 亚历克斯

【问题讨论】:

  • 听起来您需要对 service worker 安装进行门控,以免尝试在节点环境中注册。
  • @abraham 是什么意思?我热衷于追踪任何可能的线索和想法。
  • 愚蠢的问题可能......连接是否需要在 https 中端到端才能工作?反向代理终止 SSL?
  • 我现在对我的问题有了更深入的了解。我现在将分享更新。
  • @aorfevre 你解决了这个问题吗

标签: angular progressive-web-apps server-side-rendering angular-service-worker


【解决方案1】:

它实际上与您的服务器完全无关。问题是,Service Worker 试图在服务器端注册,这是不支持的。您可以做的是让服务人员在客户端注册。

我没有尝试过,但这可能对你有用。您需要在index.html 中的body 末尾放置一个单独的脚本才能在浏览器上运行:

  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/ngsw-worker.js');
    }
  </script>

请注意,这只会为您提供服务工作者的基本缓存功能,并且可能不适用于SwPushSwUpdate。您可以检查 service worker 模块在内部是如何工作的 here

您应该知道的另一件事是,Service Worker 实际上并不适合 SSR 应用。生成的ngsw.json 文件不会包含您拥有的所有页面。您必须手动修改此文件,或者不将其作为静态文件提供,而是动态创建。

缓存所有页面并不是你想做的事情(除非页面内容是静态的)。因为缓存页面将始终显示相同的内容,因为您没有在客户端执行 XHR 请求。例如,如果您的主页为客户端缓存,则该客户端将始终看到相同的页面,而不管预期的动态内容如何。

此时你应该考虑一下为什么要同时使用 SSR 和 Web APP。如果您需要 SSR 进行 SEO,则不需要 SW。当用户代理是爬虫时只做 SSR,当客户端是普通用户时提供动态角度。

如何根据用户代理切换请求

这是我的想法,我不知道是否有人这样做。但从理论上讲,它应该有效。

首先,您必须使用服务器端和客户端呈现配置将您的应用程序构建到两个不同的目录(在我的示例中为DIST_FOLDER/ssrDIST_FOLDER/csr)。您可以从 SSR 中排除 SW。您可以像往常一样在 CSR 中使用 SW。

我发现this package 可以检测爬虫/机器人用户代理。对于 express 和 Angular,您可以像这样使用它:

app.get('*', (req, res) => {
  var CrawlerDetector = new Crawler(req)

  // check the current visitor's useragent
  if (CrawlerDetector.isCrawler())
  {
    // render the index html at server side
    res.render(path.join(DIST_FOLDER, 'ssr', 'index.html'), { req });
  }
  else {
    // serve static index.html file built without SSR and let the client render it
    res.sendFile(path.join(DIST_FOLDER, 'csr', 'index.html'));
  }
});

实现此功能后,您可以通过将用户代理更改为写入 here 的用户代理(即使用 Postman)来调试应用程序以查看其是否正常工作。

【讨论】:

  • 嗨;听起来你的回答完全有道理,这似乎是我的问题的原因。我需要 SSR 来进行 SEO,我需要 Service Worker 来通知浏览器。你会如何建议这样做?
  • P.S:我会在几个小时内获得 100 Bounty 奖励;只是想引起你对我关于这一点的最后一个问题的关注。
  • @aorfevre 添加了显示如何处理请求的附加代码。让我知道这是否对您有用,因为它将来可能对我有用。对于赏金,只要你觉得合适就奖励它。
  • 您的建议是拥有 2 台服务器,一台用于具有 ssr 的爬虫,一台用于具有 pwa 的客户端。如果是,我可以用负载均衡器处理这个
  • 谢谢,我现在好多了 :),在将我们的(大)角站点更改为 ssr 的紧张一周之后,这是迄今为止最好的解决方案。
【解决方案2】:

ma​​in.browser.ts

中对#13351 进行一些“很好”的解决方法可以在Angular 10 上进行操作
// Workaround for service worker, issue #13351.
document.addEventListener('DOMContentLoaded', () => {
  platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .then(() => {
      if ('serviceWorker' in navigator && environment.production) {
        navigator.serviceWorker.register('./ngsw-worker.js');
      }
    })
    .catch((err) => console.error(err));
});

ngsw-config.json 中,我编辑了index 以引用index2.html 而不是index.html。在我的情况下,这需要在 Firebase/NestJS 上正确呈现 SSR 根 (/) 路径。

ngsw-config.json

{
  "$schema": "../../node_modules/@angular/service-worker/config/schema.json",      
  "index": "/index2.html",
  ...
}

当在Chrome DevTools 中使用prod 标志运行时 -> Application -> Service Workers 可以看到它。 View Page Source 显示 SSR。我还可以通过 Chrome 在我的桌面上添加安装应用程序。除此之外,该应用程序还可以离线工作。两者均可,通过移动浏览器和桌面应用程序。

不知道为什么默认的移动通知,即Add to home screen 没有弹出。

【讨论】:

    【解决方案3】:

    当您将 Angular PWA(服务工作者)转到 Angular SSR 项目时。

    • 请在您的 ngsw-config.json 文件中添加“navigationURLs:[]”

    下面的屏幕截图将在视图源上绑定 SSR html。

    【讨论】:

      猜你喜欢
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      • 2018-09-29
      • 2020-02-05
      • 2020-11-25
      • 2020-11-20
      • 1970-01-01
      • 2019-01-08
      相关资源
      最近更新 更多