[英]Angular 7 - Service Worker PWA + SSR not working on server
I am struggling to make my Server Side Rendering and Service Worker cooperate on server Side.我正在努力让我的服务器端渲染和 Service Worker 在服务器端合作。
Information regarding localhost -> Working有关本地主机的信息-> 工作
This is working as expected.这按预期工作。 The service worker works and updates my app on every update.
服务工作者在每次更新时都会工作并更新我的应用程序。 Moreover;
而且; a
curl localhost:8082
send me back my info.一个
curl localhost:8082
给我发回我的信息。
I start my app with the following command : npm run ssr
我使用以下命令启动我的应用程序:
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"
Information regarding production: -> Not Working有关生产的信息: -> 不工作
Website is over HTTPS : https://airdropers.io Website process is running on a close port and has HAPROXY redirecting traffic from 443 to the port of the webserver网站通过 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
网络服务器日志上可见的问题:无法订阅通知错误:服务工作者被禁用或不受此浏览器支持
Extra info :额外信息:
Node js on localhost and production are the same: v9.0.0 I build on production with the following process :本地主机和生产上的节点 js 是相同的:v9.0.0 我使用以下过程在生产上构建:
UPDATE 23/02/2019更新 23/02/2019
I have now a deeper understanding.我现在有了更深的理解。 My issue is that I start my SSR/PWA server with a node command such as "node dist/server.js".
我的问题是我使用诸如“node dist/server.js”之类的节点命令启动了我的 SSR/PWA 服务器。
From my understanding "node dist/server.js" is not working for Service Worker (PWA) I quote ( https://angular.io/guide/service-worker-getting-started )根据我的理解,“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.
由于 ng serve 不适用于 Service Worker,因此您必须使用单独的 HTTP 服务器在本地测试您的项目。 You can use any HTTP server.
您可以使用任何 HTTP 服务器。 The example below uses the http-server package from npm.
下面的示例使用来自 npm 的 http-server 包。 To reduce the possibility of conflicts and avoid serving stale content, test on a dedicated port and disable caching.
为了减少冲突的可能性并避免提供陈旧的内容,请在专用端口上进行测试并禁用缓存。
I can not launch is with http-server dist/browser
because I will loose the SSR Capability.我无法使用
http-server dist/browser
因为我会失去 SSR 功能。
How can I start my PWA / SSR Server ?如何启动我的 PWA/SSR 服务器? What command shall I use?
我应该使用什么命令?
What build shall I do?我要做什么构建?
UPDATE 24/02/2019更新 24/02/2019
As mentioned by @Gökhan Kurt the service worker is not working properly with my SSR server.正如@Gökhan Kurt 所提到的,Service Worker 无法与我的 SSR 服务器正常工作。 I need SSR for SEO and I need a service worker for Browser Push Notification.
我需要用于 SEO 的 SSR,我需要一个用于浏览器推送通知的 Service Worker。 What solution do I have to handle Browser User Push Notification?
我有什么解决方案来处理浏览器用户推送通知? A third party lib such as One Signals?
第三方库,例如 One Signals?
Any ideas suggestions are well welcomed to help me make that work.欢迎任何想法建议来帮助我完成这项工作。 Thank you for support, Alex
感谢您的支持,亚历克斯
It is actually not related to your server at all.它实际上与您的服务器完全无关。 The problem is, service worker is tried to be registered on the server side, which is not supported.
问题是,Service Worker 尝试在服务器端注册,这是不支持的。 What you can do is make it so that service worker will register on client side.
您可以做的是让服务工作者在客户端注册。
I haven't tried but this just may work for you.我没试过,但这可能对你有用。 You need to put a separate script in the end of
body
in index.html
to run on browser:您需要在
index.html
的body
末尾放置一个单独的脚本才能在浏览器上运行:
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/ngsw-worker.js');
}
</script>
Be aware that this will only give you the basic caching functionality of service worker and will probably not work for SwPush
or SwUpdate
.请注意,这只会为您提供 Service Worker 的基本缓存功能,可能不适用于
SwPush
或SwUpdate
。 You can check how service worker module works internally here .您可以在此处检查 service worker 模块的内部工作方式。
Another thing you should know is, service workers are actually not suitable for SSR apps.你应该知道的另一件事是,Service Worker 实际上并不适合 SSR 应用程序。 The generated
ngsw.json
file will not include all the pages you have.生成的
ngsw.json
文件不会包含您拥有的所有页面。 You will have to either modify this file manually or serve it not as a static file but create it dynamically.您将不得不手动修改此文件,或者不将其作为静态文件提供,而是动态创建它。
And Caching all the pages is not a thing you want to do (unless page contents are static).并且缓存所有页面不是您想要做的事情(除非页面内容是静态的)。 Because a cached page will always show the same thing since you are not doing an XHR request on client side.
因为缓存页面将始终显示相同的内容,因为您没有在客户端执行 XHR 请求。 For example if your home page is cached for a client, that client will always see the same page regardless of the intended dynamic content.
例如,如果您的主页是为客户端缓存的,那么无论预期的动态内容如何,该客户端将始终看到相同的页面。
At this point you should consider why you want SSR and Web APP at the same time.这时候你应该考虑一下为什么要同时需要SSR和Web APP。 If you need SSR for SEO, you don't need a SW.
如果您需要 SSR 进行 SEO,则不需要 SW。 Just do SSR when the user agent is of a crawler, and serve dynamic angular when the client is a normal user.
用户代理是爬虫的时候做SSR,客户端是普通用户的时候做动态angular。
How to switch request based on User Agent如何基于用户代理切换请求
This is my thought and I don't know if anyone is doing this.这是我的想法,我不知道是否有人这样做。 But theoretically, it should work.
但从理论上讲,它应该有效。
Firstly, you will have to build your app to two different directories ( DIST_FOLDER/ssr
and DIST_FOLDER/csr
in my example) with server-side and client-side rendering configurations.首先,您必须使用服务器端和客户端渲染配置将应用程序构建到两个不同的目录(在我的示例中为
DIST_FOLDER/ssr
和DIST_FOLDER/csr
)。 You may exclude SW from SSR.您可以从 SSR 中排除 SW。 You can use SW in CSR as usual.
您可以像往常一样在 CSR 中使用 SW。
I found this package that can detect crawler/bot user agents.我发现这个包可以检测爬虫/机器人用户代理。 For express and Angular, you would use it like:
对于 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'));
}
});
After implementing this, you can debug your application to see if it works correctly by changing your user agent to one that is written here (ie use Postman).实现这一点后,您可以通过将用户代理更改为此处编写的用户代理(即使用 Postman)来调试您的应用程序以查看它是否正常工作。
With a little "good-to-have" workaround to #13351 got this working on Angular 10
by quite little change in main.browser.ts通过对#13351的一些“有益的”解决方法,在main.browser.ts 中几乎没有变化就可以在
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));
});
In the ngsw-config.json
I've edited index
to refer to index2.html
instead of index.html
.在
ngsw-config.json
我编辑了index
来引用index2.html
而不是index.html
。 That's needed in my case to render SSR on Firebase
/ NestJS
properly the root ( /
) path.在我的情况下,需要在
Firebase
/ NestJS
正确呈现根 ( /
) 路径的 SSR。
ngsw-config.json ngsw-config.json
{
"$schema": "../../node_modules/@angular/service-worker/config/schema.json",
"index": "/index2.html",
...
}
When running with prod
flag in the Chrome DevTools
-> Application
-> Service Workers
can see it.在
Chrome DevTools
-> Application
-> Service Workers
使用prod
标志运行时可以看到它。 View Page Source
shows SSR. View Page Source
显示 SSR。 I can also add the install the application via Chrome on my desktop.我还可以通过 Chrome 在我的桌面上添加安装应用程序。 In addition to that, the application works offline.
除此之外,该应用程序可以离线工作。 Both, via mobile browser, and desktop app.
两者,通过移动浏览器和桌面应用程序。
Can't why default mobile notification, ie Add to home screen
isn't popping up.不知道为什么没有弹出默认的移动通知,即
Add to home screen
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.