首页 文章

使用@ angular / service-worker缓存Google Maps API

提问于
浏览
5

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

我无法设法缓存并提供Google Maps API请求(例如磁贴) . 在线时不会缓存响应,因此在离线时也不会提供响应 .

我尝试了什么:

  • 将 Map URL添加到dataGroups:No Error,但也没有缓存,当脱机时我得到以下错误:

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

  • 将 Map URL添加到assetGroups installMode:prefetch,我在尝试预取时遇到跨源错误:

请求的资源上没有'Access-Control-Allow-Origin'标头 . 原始'http://localhost:8080 ' is therefore not allowed access. If an opaque response serves your needs, set the request'模式到'no-cors'获取禁用CORS的资源 .

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

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

我的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"
        }
    }]
}

很高兴在需要时提供更多信息 .

2 回答

  • 1

    我也正在与谷歌 Map 的服务工作者一起工作,如果我在 assetGroups -> urls 插入它 "https://maps.googleapis.com/maps/**"

    "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/**"
    ]
    
  • 1

    基本上,Google Map 只接受无人请求 . 如果您将请求配置为https:// maps.googleapis.com为无人模式,则该请求将被服务器拒绝 .

    您必须只允许无人请求,然后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缓存中返回它,因此我们必须确保始终从网络中获取它 . 否则,我们的提取不会失败,我们会获得谷歌 Map 控件(来自缓存),但它下面没有 Map ( Map 数据不会被缓存) . 我们通过将cache选项设置为no-store来完成此操作,该选项完全跳过缓存 .

    遗憾的是,在编写本文时,所有浏览器仍然不支持此选项,因此请为每个请求的查询字符串添加缓存清除时间戳,以确保每个请求都是唯一的并跳过缓存 . 我们通过将当前时间附加到每个请求的URL来完成此操作 .

    这是我在一本好书中读到的解决方案的修改:Ater,Tal . 构建渐进式Web应用程序:为浏览器O'Reilly Media带来本机的强大功能 .

相关问题