如何在Angular 5+ Service Worker中处理路由? [英] How to handle routing in Angular 5+ Service Workers?
问题描述
在以前版本的Angular Service Worker实现中,配置选项之一是 routing
。可以在此
In previous versions of the Angular service worker implementation, one of the config options was "routing"
. This can be seen in this unanswered SO question, was referenced in this Angular CLI issue, and the best remaining documentation seems to be the blog post by Stephen Fluin (on the Angular team), as well as the I/O talk from Alex Rickabaugh (from Google).
对于Angular 5, ServiceWorkerModule
已被很好地构建,并且大多数配置现在都可以使用<$ c $处理c> ngsw-config.json 文件。但是,在 angular.io指南中的任何地方,都不再提及如何处理路由重定向。 ,或在文档中。因此,我遇到了以下问题:当我访问我的应用程序并脱机时,直接访问它时我仍然可以访问该应用程序: https://jackkoppa.github.io/cityaq-sw-issue 。但是,加载后,该应用程序将重定向到 search
路由,并且大多数用户会尝试从类似 https://jackkoppa.github.io/cityaq-sw-issue/search?cities=Shanghai (为简单起见,我我现在只是在谈论Chrome桌面和移动设备,并在可能的情况下使用隐身模式。)
With Angular 5, the ServiceWorkerModule
has been well built-out, and most of the configuration can now be handled using the ngsw-config.json
file. However, there is no longer any mention of how to handle redirection for routes, anywhere in the angular.io guide, or in the documentation. So I end up with the following problem: when I have visited my app and go offline, I can still access the app when visiting it directly: https://jackkoppa.github.io/cityaq-sw-issue. However, upon load the app redirects to the search
route, and most users would be trying to load from a URL like https://jackkoppa.github.io/cityaq-sw-issue/search?cities=Shanghai (for simplicity, I'm just talking about Chrome desktop & mobile, for now, and in Incognito when possible).
当您尝试离线访问该URL时,您会立即获得504 -网关超时。之所以发生这种情况,是因为服务工作者仅缓存了索引,并且不知道其他路由应重定向到该索引以便可以加载。我相信Angular Service Worker实施的先前迭代可以通过为给定路由设置重定向到索引的方式来解决这种情况。 是否可以在当前的Angular 5+ ngsw-config.json
或生成的 ngsw.json中处理此重定向
文件?除非这样做,否则应如何在单独的Service Worker JS文件中处理替代方法?
When you try to visit that URL while offline, you immediately get 504 - Gateway Timeout. This is happening because the service worker has only cached the index, and doesn't know that other routes should redirect to the index so that it can load. I'm confident that previous iterations of the Angular service worker implementation could have handled this scenario, by setting up redirects to the index for given routes. Is there a way to handle this redirect in the current, Angular 5+ ngsw-config.json
, or in the generated ngsw.json
file? Barring that, how should a workaround be handled in a separate service worker JS file?
推荐答案
TL ; DR:;我已经确定了至少两个导致案件破裂的问题;您现在可以使用此构建脚本尝试我的修复,并查看应用程序脱机工作此处。进一步测试和
TL;DR: I've identified at least two issues causing breakage in my case; you can use this build script for now to try my fix, and see the app work offline here. Further testing & pull requests needed.
虽然我无法找到有据可查的答案,但这是我能够找到的答案找到到目前为止,逐步浏览 ngsw-worker.js
文件,以及阅读 @ angular / service-worker
提交历史记录。
While I've been unable to find a documented answer, here's what I've been able to find thus far, in stepping through the ngsw-worker.js
file, as well as reading the @angular/service-worker
commit history.
新的 ServiceWorkerModule
处理路由的方法是接受任何导航请求(即同一域上的非索引路由),然后重新运行 handleFetch
方法,但现在指向 index.html
请求(源)。鉴于SPA在检索到索引的缓存文件后应该能够将其重定向到URL,因此此方法应该可以正常工作。
The new ServiceWorkerModule
approach to "routing" is to take any "navigation" request (i.e. a non-index route on the same domain), and re-run the handleFetch
method, but now pointing to the index.html
request (source). This should work fine, given an SPA should be able to redirect to the URL once it has retrieved its cached files for the index.
所以导致我的网站出现问题上述问题在离线时失败一定与路由没有直接关系,到目前为止,我发现2。通过变通办法纠正这些问题,使我的应用程序可以按预期运行。通过原始问题中的repro步骤, cityaq 现在可以正常工作了,而我已经复制了原始问题,但是失败了网站 cityaq-sw-issue 。
So the problems that are causing my site above to fail when offline must not be directly related to routing, and I've found 2 thus far. Correcting these with a workaround has allowed me to get my app working mostly as expected. With the repro steps in the original question, cityaq is now working, while I've reproduced the original, failing site at cityaq-sw-issue.
问题:
-
Angular应用程序的托管版本,其中
-base-href
标志是从CLI设置的,列出了其服务工作者资源的绝对URL。在比较对这些资源的请求时,ngsw-worker.js
期望相对URL
Hosted versions of an Angular app, where the
--base-href
flag is set from the CLI, list absolute URLs for their service worker resources. When comparing requests to these resources,ngsw-worker.js
is expecting relative URLs
- source
- I'm fairly confident this issue needs to be resolved, and I'll be working on a pull request to fix it. It happens because the
baseHref
is getting included in the resource URLs whenngsw.json
is generated (source)
ngsw-worker.js
可以位于的三个可用状态中,根据我的经验, EXISTING_CLIENTS_ONLY
似乎设置有误。
Of the 3 available "states" that the ngsw-worker.js
can be in, in my experience, EXISTING_CLIENTS_ONLY
seems to bet set incorrectly.
- 源1 ,源2
- 我对此更改不太有把握,因为我一直无法始终看到什么导致此状态。但是,如果&当服务工作者进入此状态时,
ngsw-worker.js
将不再尝试检索缓存的资源(源),在我看来是正确情况下的测试中,即使唯一的更改是删除互联网连接,应用程序仍会进入此状态
- source 1, source 2
- I'm less confident about this change, because I haven't been able to consistently see what causes this state. However, if & when the service worker enters this state,
ngsw-worker.js
will no longer attempt to retrieve cached resources (source), and in my testing under what seem to be "correct" circumstances, the app still enters this state even when the only change is removing an internet connection
虽然我为第1个问题整理了PR,并等待了解第2个问题的帮助,但我正在使用一种变通方法构建脚本来修改 ngsw-worker.js
它生成了。警告:这很丑陋肯定会修改设置 EXISTING_CLIENTS_ONLY
的预期安全行为。但是,对于我的应用程序,它既可以在本地运行( http-server
),又可以部署到实时URL(在我的情况下为GitHub页面)中,均具有正确的脱机性能。
While I put together a PR for issue #1, and wait for some help understanding issue #2, I'm using a workaround build script to modify ngsw-worker.js
after it's generated. Warning: it's ugly & definitely modifies the intended "safe" behavior of setting EXISTING_CLIENTS_ONLY
. However, for my app, it does allow correct offline performance both when running locally (http-server
), and deploying to a live URL (GitHub pages, in my case).
要使用变通方法:
(Angular 5,经过Angular 5.2.1测试)
To use the workaround: (Angular 5, tested w/ Angular 5.2.1)
-
npm安装替换文件--save-dev
- 在您的应用程序中包含此脚本在
build / fix-sw.js
中 - 在您的
package.json $中c $ c>:
npm install replace-in-file --save-dev
- Include this script in your app, e.g. at
build/fix-sw.js
- In your
package.json
:
"scripts": {
...
"sw-build": "ng build --prod && node build/fix-sw",
"sw-build-live": ng build --prod --base-href https://your-url.com/ && node build/fix-sw"
...
}
- 要在本地运行
npm run sw-build
cd dist
http-server -p 8080
- 并在发送到服务器之前为您的实时URL准备构建(例如,使用 angular-cli-ghpages )
- And to prepare a build for your live URL, before sending to a server (e.g. with angular-cli-ghpages)
npm run sw-build-live
这篇关于如何在Angular 5+ Service Worker中处理路由?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!