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

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

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

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

这按预期工作。服务 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. 拉动
  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 )

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?


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

最佳答案

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

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

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

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

另一件你应该知道的事情是,Service Worker 其实并不适合 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可以检测爬虫/机器人用户代理。对于 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)。

关于Angular 7 - Service Worker PWA + SSR 无法在服务器上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54633477/

相关文章:

angular - 如何找到添加到 leafletLayer 的多个标记的边界

angular - ng-cli 不会将组件添加到应用程序模块

javascript - 在 iOS 中使用 JavaScript 在 PWA 中显示服务器生成的图像

reactjs - 错误 : getStaticPaths is required for dynamic SSG pages and is missing for "xxx". NextJS

javascript - Angular 7 SSR,应用程序组件 ngOnInit() 被多次调用

Nginx、nuxt.js 静态生成模式和尾部斜杠重定向

javascript - 如何在客户端的 Angular 应用程序中记录所有可能发生的控制台错误?

Angular APP_INITIALIZER 是否在延迟加载的模块中工作

vue.js - PWA 的路由器部分在设备上打开空白(使用 Vue)

javascript - 使用 JavaScript 删除网站上所有客户端存储的数据