如何禁用 Angular service-worker 的预检缓存控制标头(调用事件流时)?

4 http-status-code-504 server-sent-events preflight service-worker angular

更新2:请参阅下面我的回答。504错误已修复

cache-control更新:尽管存在错误,但这似乎不是由于标头造成的。如果我禁用服务工作线程,标头仍然存在。相反,这是由于504 (Gateway Timeout)API 上的 Service Worker 造成的。知道如何解决这个问题吗?

我已经构建了一个完整的 MEAN-stack 应用程序,并且在我使用 Service Worker 之前它工作得很好。

我得到的主要错误是

Failed to load ${apiUrl} Request header field Cache-Control is not allowed by Access-Control-Allow-Headers in preflight response.

我在尝试访问外部 API (api.article.io) 时收到此消息,我无法控制其 CORS 设置。

我尝试ngsw-config.json通过将 API url 添加到 来调整我的dataGroups,但到目前为止,这只增加了一个额外的错误:

Uncaught (in promise) TypeError: Failed to fetch ngsw-worker.js

仅当尝试使用以下方式获取事件流时才会发生这种情况:

watchStatus(url: string): Observable<eventResponse> {
        return new Observable<eventResponse>(obs => {
            const source = new EventSource(url);
            source.addEventListener('status', (event) => {
                obs.next(JSON.parse(event.data).data);
            });
            return () => source.close();
        });
    }
Run Code Online (Sandbox Code Playgroud)

有没有办法用可观察的来调用它?如果没有 ,我无法让服务器发送的事件正常工作EventSource,但也许我做错了。

我的ngsw-config.json

{
  "index": "/index.html",
  "assetGroups": [{
    "name": "app",
    "installMode": "prefetch",
    "resources": {
      "files": [
        "/favicon.ico",
        "/index.html",
        "/*.css",
        "/*.js"
      ]
    }
  }, {
    "name": "assets",
    "installMode": "lazy",
    "updateMode": "prefetch",
    "resources": {
      "files": [
        "/assets/**"
      ]
    }
  }, {
    "name": "fonts",
    "resources": {
      "urls": [
        "https://fonts.googleapis.com/**",
        "https://fonts.gstatic.com/**"
      ]
    }
}],
  "dataGroups": [
      {
          "name": "photon-api",
          "urls": [
              "http://api.particle.io/**",
              "https://api.particle.io/**"
          ],
          "cacheConfig" : {
              "strategy": "freshness",
              "maxSize": 0,
              "maxAge": "0u"
          }
      }
  ]
}
Run Code Online (Sandbox Code Playgroud)

是否可以禁用预检Cache-Control标头更改我的ngsw-config.json

小智 5

知道了!

我根据此处找到的 github 问题答案修复了它。

基本上,服务人员可以用 捕获所有内容onFetch。为了将我的 API URL 列入白名单,我打开ngsw-worker.js并更改onFetch(event)为:

onFetch(event) {
    const req = event.request;
    // List of words in request URL to whitelist/bypass the service worker
    const whitelist = ['api', 'otherWhitelistWords...']
    // Check to see if request url contains any whitelisted words and skip the rest of onFetch if it does
    if (whitelist.some(word => req.url.toLowerCase().includes(word.toLowerCase()))) {
                return
    }
   ...
}
Run Code Online (Sandbox Code Playgroud)

ng build:prod您可以通过创建以下内容来自动修复fix-sw.sh

#!/bin/bash
sed -i "/onFetch(event) {/,/const req = event.request;/c onFetch(event){const req=event.request;const whitelist=['api','otherWhitelistWords...'];if(whitelist.some(word=>req.url.toLowerCase().includes(word.toLowerCase()))){return}" ./dist/${PROJECTNAME}/ngsw-worker.js
Run Code Online (Sandbox Code Playgroud)

然后,在 中package.json,将您的更改build:prod为:

"build:prod": "ng build --prod && bash ./fix-sw.sh",
Run Code Online (Sandbox Code Playgroud)