Angular 5和Service Worker:如何从ngsw-config.json中排除特定路径

42

我有一个 ngsw-config.json 文件(来自文档):

    {
      "index": "/index.html",
      "assetGroups": [{
        "name": "app",
        "installMode": "prefetch",
        "resources": {
          "files": [
            "/favicon.ico",
            "/index.html"
          ],
          "versionedFiles": [
            "/*.bundle.css",
            "/*.bundle.js",
            "/*.chunk.js"
          ]
        }
      }, {
        "name": "assets",
        "installMode": "lazy",
        "updateMode": "prefetch",
        "resources": {
          "files": [
            "/assets/**"
          ]
        }
      }]
    }

在我的网站上有一个指向RSS订阅源/api/rss的链接,希望能够在不加载Angular应用程序的情况下在新标签页中打开。我该如何将其从资源列表中排除,使其不会被重定向到index.html?

更新:我尝试使用以下配置但未成功(请参见!/api/rss):

    {
      "index": "/index.html",
      "assetGroups": [{
        "name": "app",
        "installMode": "prefetch",
        "patterns": ["!/api/rss"],
        "resources": {
          "files": [
            "/favicon.ico",
            "/index.html",
            "!/api/rss"
          ],
          "versionedFiles": [
            "/*.bundle.css",
            "/*.bundle.js",
            "/*.chunk.js"
          ]
        }
      }, {
        "name": "assets",
        "installMode": "lazy",
        "updateMode": "prefetch",
        "resources": {
          "files": [
            "/assets/**"
          ]
        }
      }]
    }

如果我没理解错的话,您想要使用路由/api/rss,该路由指向某个不属于您的Angular应用程序或页面视图的其他位置,并且服务工作者不应从该URL加载任何内容。 - Panna Das
@PannaDas,Angular应用程序不应提供此URL。 - ktretyak
7个回答

45

感谢Pedro Arantes建议,我成功实现了下一个工作配置(请查看dataGroups"maxAge": "0u"):

{
  "index": "/index.html",
  "dataGroups":
  [
    {
      "name": "api",
      "urls": ["/api"],
      "cacheConfig": {
        "maxSize": 0,
        "maxAge": "0u",
        "strategy": "freshness"
      }
    }
  ],
  "assetGroups":
  [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html"
        ],
        "versionedFiles": [
          "/*.bundle.css",
          "/*.bundle.js",
          "/*.chunk.js"
        ]
      }
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": [
          "/assets/**"
        ]
      }
    }
  ]
}

2
我放在Datagroups中的所有内容似乎都被忽略了。我在使用“ng build --prod”生成的ngsw.json文件中没有看到datagroup。您是否使用此配置或以其他方式工作? - switch
1
这仅适用于GET请求。 当文件进度条由于SW而无法工作时,我们遇到了问题。 我们已经按照此处建议的解决方案进行了操作:https://github.com/angular/angular/issues/21191#issuecomment-360051276,直到Angular添加本地支持。 - doron
4
它对外部链接(例如CDN文件)也有效吗?我正在尝试,但对我来说不起作用。 - Borad Akash
这种方法对我来说不起作用;只有通过使用ngsw-bypass从https://dev59.com/PFYN5IYBdhLWcg3wRmah#58520498绕过Angular服务工作者的URL才有效。 - Tang Thanh Tam

22

您是否已经尝试创建数据组?dataGroups被用于像assetGroups这样的数据请求,用于获取资产(即文件)。

数据组

与资源资产不同,数据请求不会随着应用程序一起进行版本控制。它们根据手动配置的策略缓存,更适用于诸如API请求和其他数据依赖关系之类的情况。

数据组接口:

export interface DataGroup {
  name: string;
  urls: string[];
  version?: number;
  cacheConfig: {
    maxSize: number;
    maxAge: string;
    timeout?: string;
    strategy?: 'freshness' | 'performance';
  };
}

您可以创建一个数据组,其中排除/api/rss(如果"!/api/rss"不起作用,则可以在"urls": ["/api/user", "/api/admin"]中添加所有其他 API):

{
  "index": "/index.html",
  "assetGroups": [{
    "name": "assetGroup1",
    ...
  }, {
    "name": "assetGroup1",
    ...
  }],
  "dataGroups": [{
    "name": "dataGroup1";
    "urls": ["!/api/rss"];
    cacheConfig: {
      maxSize: 50;
      maxAge: "3d12h";
    }
  }, {
    "name": "dataGroup2";
    "urls": ["/api/user"];
    cacheConfig: {
      maxSize: 40;
      maxAge: "3d12h";
    }
  }]
}

数据组URL中不支持负全局模式。请参见https://angular.io/guide/service-worker-config#urls。 - grigson
我需要服务工作者停止缓存GET请求。 - sgClaudia98

21
现在可以更容易地通过使用 ngsw-bypass 来绕过 Angular 服务工作者的 URL。来自文档:

要绕过服务工作器,您可以将 ngsw-bypass 设置为请求标头或查询参数。(标头或查询参数的值将被忽略,可以为空或省略。)

我正在使用查询字符串来从服务工作者中绕过某些url,像这样:

https://mydomain.report-uri.com/r/d/csp/enforce?ngsw-bypass=true


2
这绝对是比被接受的答案更好的答案。因为现在你不必编辑ngsw-config.json文件,我认为最好将其保持原样(如果可能的话),以便于未来的更新。 - Ramo Mislimi
这对我不起作用,它完全忽略了ngsw-bypass参数和ngsw-bypass头。 - sgClaudia98

14

正确的做法是在索引重定向中省略端点。因此,您的ngsw-config.json应该像这样添加navigationUrls并否定您希望省略的URL部分。这样,URL将只是被重定向并绕过ngSW。

    {
      "index": "/index.html",
      "assetGroups": [{
        "name": "app",
        "installMode": "prefetch",
        "resources": {
          "files": [
            "/favicon.ico",
            "/index.html"
          ],
          "versionedFiles": [
            "/*.bundle.css",
            "/*.bundle.js",
            "/*.chunk.js"
          ]
        }
      }, {
        "name": "assets",
        "installMode": "lazy",
        "updateMode": "prefetch",
        "resources": {
          "files": [
            "/assets/**"
          ]
        }
      }],
      "navigationUrls": [
        "!/api/rss"
      ]
    }

请注意!/api/rss是具体的。如果您想要省略整个api文件夹,请使用!/api/**

文档在此处https://angular.io/guide/service-worker-config#navigationurls

请注意,根据文档,在"资源":"网址":下否定(!)不起作用。


2
我认为你的解决方案是最好的!但你还需要包括文档中的默认导航URL:"navigationUrls": [ "/**", "!/**/*.*", "!/**/*__*", "!/**/*__*/**", "!/api/rss"] - illnr
我尝试过这个,但它没有起作用。我的navigationUrls之一是"!/web/v3/Account/connect/**/**",而当使用window.open()时,url /web/v3/Account/connect/web/microsoft 仍在PWA中打开。 - Pieterjan
@Pieterjan,你找到解决方法了吗? - sgClaudia98
如果子域名对您不可用,这里是错误跟踪问题 - Pieterjan
  • TwoFactorSigninAsync 很可能需要从同一域调用,因此如果您通过例如 Microsoft 进行登录,则需要导航到 MVC 视图以请求 2FA 代码。
- Pieterjan
显示剩余2条评论

4
ngsw-configuration.json 文件使用 glob 格式来匹配路径。
Patterns use a limited glob format:

** matches 0 or more path segments.
* matches exactly one path segment or filename segment.
The ! prefix marks the pattern as being negative, meaning that only files that don't match the pattern will be included.

这里重要的是前缀!,可用于排除某个路径。例如,一个匹配模式!/api/rss应该排除此路径。
为了从您的nags-configuration.json文件中排除某个路径,只需在该路径模式之前添加!字符。

1
这是我尝试做的第一件事情(像这样),但它不起作用。 - ktretyak
你尝试过其他变体,比如 !api/rss 或者 !/api/rss/** 吗? - Trent
6
请注意,dataGroups中的urls数组或AssetGroups/resources中的files数组不支持负面全局模式。 - obaylis
那么它们在哪里得到支持呢,@obaylis。 - Ákos Vandra-Meyer
@ÁkosVandra - 你可以在这里找到关于支持/不支持的详细信息 - https://angular.io/guide/service-worker-config - obaylis
请您能否添加一个实际的例子? - Mohammad Kermani

0

0
在 ngsw-config.json 文件中。
{
  "index": "/index.html",
  "dataGroups":
  [
    {
      "name": "api",
      "urls": ["!/**/*profileimageupload*"],
      "cacheConfig": {
        "maxSize": 0,
        "maxAge": "0u",
        "strategy": "freshness"
      }
    }
  ]  
}

例如,如果您的API类似于https://api.example.com/profileimageupload/,则添加服务/API的最后一段

我添加了profileimageupload,我想从服务工作者中排除(删除)调用它,这就是为什么我添加了!/**/yourService/Api last name


https://angular.io/guide/service-worker-config#urls:不支持负的全局模式。 - Remco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接