Angular 7 - Service Worker PWA + SSR 无法在服务器上运行

Angular 7 - Service Worker PWA + SSR not working on server

我正在努力让我的服务器端渲染和 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 重定向到网络服务器的端口

Issue visible on Webserver logs : Could not subscribe to notifications Error: Service workers are disabled or not supported by this browser

额外信息:

localhost 和 production 上的 Node js 相同:v9.0.0 我使用以下过程构建生产:

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

更新 23/02/2019

我现在有了更深的理解。 我的问题是我使用 "node dist/server.js".

等节点命令启动我的 SSR/PWA 服务器

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

Because ng serve does not work with service workers, you must use a separate HTTP server to test your project locally. You can use any HTTP server. The example below uses the http-server package from npm. To reduce the possibility of conflicts and avoid serving stale content, test on a dedicated port and disable caching.

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

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

2019 年 2 月 24 日更新

正如@Gökhan Kurt 所提到的,service worker 无法在我的 SSR 服务器上正常工作。 我需要 SSR 来进行 SEO,我需要一个 service worker 来进行浏览器推送通知。 我必须使用什么解决方案来处理浏览器用户推送通知?第三方库,例如 One Signals?


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

其实跟你的服务器一点关系都没有。问题是,服务工作者试图在服务器端注册,这是不支持的。您可以做的是让服务工作者在客户端注册。

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

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

请注意,这只会为您提供 Service Worker 的基本缓存功能,可能不适用于 SwPushSwUpdate。您可以检查 Service Worker 模块在内部是如何工作的 here.

还有一点你要知道,service workers其实并不适合做SSR应用。生成的 ngsw.json 文件不会包含您拥有的所有页面。您将必须手动修改此文件或不将其作为静态文件提供,而是动态创建。

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

此时你应该考虑一下为什么要同时要SSR和Web APP。如果您需要 SSR 来进行 SEO,则不需要 SW。当user agent是爬虫的时候就做SSR,当client是普通用户的时候serve dynamic angular。

如何根据User Agent切换请求

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

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

我发现 this package 可以检测 crawler/bot 用户代理。对于 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)。

通过 #13351 的一些“可有可无”的解决方法,在 main.browser.ts

// 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",
  ...
}

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

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

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

  • Kindly add "navigationURLs:[]" in your ngsw-config.json file

下面的截图将绑定 SSR html 查看源代码。