本文介绍了如何在 Angular 5+ Service Workers 中处理路由?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在之前版本的 Angular Service Worker 实现中,配置选项之一是 "routing".这可以在这个未回答的SO问题中看到,在这个Angular CLI 问题,剩下的最好的文档似乎是 Stephen Fluin 的博客文章(在 Angular 团队中),以及 I/O 谈话,来自 Alex Rickabaugh(来自 Google).

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 得到了很好的构建,现在可以使用 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 - 网关超时.发生这种情况是因为 Service Worker 只缓存了索引,并且不知道其他路由应该重定向到索引以便它可以加载.我相信 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路由"方法是接受任何导航"请求(即同一域上的非索引路由),并重新运行handleFetchcode> 方法,但现在指向 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 个.使用变通方法纠正这些问题使我的应用程序大致按预期工作.通过原始问题中的重现步骤,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.

问题:

  1. Angular 应用的托管版本,其中 --base-href 标志是从 CLI 设置的,列出其服务工作线程资源的绝对 URL.将请求与这些资源进行比较时,ngsw-worker.js 需要相对 URL

  1. 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

  • 来源
  • 我非常有信心需要解决这个问题,我将处理拉取请求来修复它.这是因为 baseHref 在生成 ngsw.json 时被包含在资源 URL 中(source)
  • 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 when ngsw.json is generated (source)

ngsw-worker.js 可以处于的 3 个可用状态"中,根据我的经验,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.

  • 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)

  1. npm install replace-in-file --save-dev
  2. 在您的应用中包含此脚本,例如在 build/fix-sw.js
  3. 在您的 package.json 中:
  1. npm install replace-in-file --save-dev
  2. Include this script in your app, e.g. at build/fix-sw.js
  3. 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"
   ...
}
  1. 在本地运行
npm run sw-build
cd dist
http-server -p 8080
  1. 并在发送到服务器之前为您的实时 URL 准备构建(例如使用 angular-cli-ghpages)
npm run sw-build-live

这篇关于如何在 Angular 5+ Service Workers 中处理路由?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 12:54