首页 > 解决方案 > 如何禁用 Angular 服务工作者的预检缓存控制标头(调用事件流时)?

问题描述

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

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

我已经构建了一个完整的 MEAN-stack 应用程序,在我使用服务工作者之前它运行良好。

我得到的主要错误是

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

我在尝试访问外部 API (api.particle.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();
        });
    }

有没有办法用 observable 来调用它?如果没有 ,我无法让服务器发送的事件工作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"
          }
      }
  ]
}

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

标签: angularservice-workerserver-sent-eventspreflighthttp-status-code-504

解决方案


知道了!

我根据在此处找到的 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
    }
   ...
}

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

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

"build:prod": "ng build --prod && bash ./fix-sw.sh",

推荐阅读