8

我正在开发一个 Angular 5 项目,并希望通过 @angular/service-worker 包提供 PWA 功能。

我无法缓存和提供 Google Maps API 请求(例如图块)。在线时不会缓存响应,因此离线时也不会提供响应。

我尝试了什么:

  • 将地图 URL 添加到数据组:没有错误,但也没有缓存,离线时我收到以下错误:

    错误错误:未捕获(承诺):事件:{“isTrusted”:true}(在main.bundle.js中)

  • 将 Maps URL 添加到assetGroups installMode: prefetch,尝试预取时出现跨域错误:

    请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问源“ http://localhost:8080 ”。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

  • 将 Maps URL 添加到assetGroups installMode:lazy,我得到与 installMode:prefetch 相同的结果

其余数据缓存并提供良好的服务(来自 localhost 的静态数据和来自不同端口上的 localhost API 端点的 json)。

我的 ngsw-config.json 看起来像这样:非常感谢任何指针。

{
  "index": "/index.html",
  "assetGroups": [{
    "name": "app",
    "installMode": "prefetch",
    "resources": {
      "files": [
        "/favicon.png",
        "/index.html"
      ],
      "versionedFiles": [
        "/*.bundle.css",
        "/*.bundle.js",
        "/*.chunk.js"
      ],
      "urls": [
          "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700",
          "https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmEU9fBBc4AMP6lQ.woff2",
          "https://fonts.gstatic.com/s/roboto/v18/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2"
      ]
    }
  }, {
    "name": "assets",
    "installMode": "lazy",
    "updateMode": "prefetch",
    "resources": {
      "files": [
        "/assets/**"
      ]
    }
  }],
    "dataGroups": [{
        "name": "from-api",
        "urls": [
            "/api/restaurants",
            "/img/**",
            "/icons/**",
            "https://maps.googleapis.com/maps/**"
        ],
        "cacheConfig": {
            "maxSize": 100,
            "maxAge": "1d",
            "timeout?": "3s"
        }
    }]
}

如果需要,很乐意提供更多信息。

4

2 回答 2

1

基本上,谷歌地图只接受 no-cors 请求。如果您将 https://maps.googleapis.com 的请求配置为 no-cors 模式,则该请求将被服务器拒绝。

您必须只允许 no-cors 请求,然后 Google 可以确保第三方网站可以自由地从中读取数据,但他们修改请求的能力有限:

所以,我这样做...

var googleMapsAPIJS = "https://maps.googleapis.com/maps/api/js?key =" + YOUR KEY& callback = initMap";
if (requestURL.href = = = googleMapsAPIJS) { 
    event.respondWith(
     fetch( 
    googleMapsAPIJS +"&" + Date.now(), 
        { mode: "no-cors", cache: "no-store" } 
     ).catch( function() {
//so if offline serve my static map
      return caches.match("/offline-map.html"); 
})
); 
}

由于 Google 的服务器返回 Maps API JavaScript 文件的标头会导致浏览器始终尝试从 HTTP 缓存中返回它,因此我们必须确保它始终是从网络中获取的。否则,我们的获取不会失败,我们会(从缓存中)获得 Google 地图控件,但它下面没有地图(地图数据没有被缓存)。我们通过将缓存选项设置为 no-store 来完成此操作,这会完全跳过缓存。

不幸的是,在撰写本文时,并非所有浏览器都支持此选项,因此为每个请求的查询字符串添加一个缓存清除时间戳,以确保每个请求都是唯一的并且将跳过缓存。我们通过将当前时间附加到每个请求的 URL 来做到这一点。

这是我在一本好书中读到的解决方案的修改:Ater, Tal。构建渐进式 Web 应用程序:将本机的力量带入浏览器 O'Reilly Media。

于 2018-05-23T19:38:47.483 回答
1

我也在使用谷歌地图与服务人员一起工作,如果我将它插入"https://maps.googleapis.com/maps/**"assetGroups -> urls

"urls": [
  "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700",
  "https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmEU9fBBc4AMP6lQ.woff2",
  "https://fonts.gstatic.com/s/roboto/v18/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2",
  "https://maps.googleapis.com/maps/**"
]
于 2018-03-02T00:29:58.917 回答