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
我使用以下过程构建生产:
- git拉
- npm 运行 build:ssr
- 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 的基本缓存功能,可能不适用于 SwPush
或 SwUpdate
。您可以检查 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/ssr
和 DIST_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 查看源代码。
我正在努力让我的服务器端渲染和 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 我使用以下过程构建生产:
- git拉
- npm 运行 build:ssr
- 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 的基本缓存功能,可能不适用于 SwPush
或 SwUpdate
。您可以检查 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/ssr
和 DIST_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 查看源代码。