0

我正在使用服务人员构建一个 vueJs 应用程序。我决定使用带有 InjestManifest 方法的 Workbox 来拥有自己的路线。

在线获取时: 1- 通过网络回答 2- 将正文写入 IDB(通过 localforage) 3- 发回响应

这里一切正常,sw 拦截了 fetch 并返回适当的响应,IDB 包含正确的详细信息。在线时发送回 fecth 的响应:响应 {type:“cors”,url:“ http://localhost:3005/api/events ”,重定向:false,状态:200,ok:true,...}

问题是当我离线时。我的意图是连接到 Locaforage 并检索内容并建立响应。问题是 Fetch 认为此响应不合适,然后拒绝它。Console.log 确认 sw 中的 .catch 正在工作,但看起来它发送的响应被拒绝了。这是我在离线时发送回获取的响应的 console.log;响应 {type: "default", url: "", redirected: false, status: 200, ok: true, ...}

我不知道 fetch 是否不满意,因为响应的 url 与请求上的不同,但工作箱应该允许使用其他响应而不是来自缓存或 fetch 的响应。

这是代码

importScripts('localforage.min.js')

localforage.config({
  name: 'Asso-corse'
})
workbox.skipWaiting()
workbox.clientsClaim()

workbox.routing.registerRoute(
  new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
  workbox.strategies.cacheFirst({
    cacheName: 'googleapis',
    plugins: [
      new workbox.expiration.Plugin({
        maxEntries: 30
      })
    ]
  })
)
workbox.routing.registerRoute( new RegExp('http://localhost:3005/api/'), function (event) {
  fetch(event.url)
    .then((response) => {
      var cloneRes = response.clone()
      console.log(cloneRes)
      cloneRes.json()
      .then((body) => {
        localforage.setItem(event.url.pathname, body)
      })
      return response
    })
    .catch(function (error) {
      console.warn(`Constructing a fallback response, due to an error while fetching the real response:, ${error}`)
        localforage.getItem(event.url.pathname)
        .then((res) => {
         let payload = new Response(JSON.stringify(res), { "status" : 200 , 
    "statusText" : "MyCustomResponse!" })
         console.log(payload)
        return payload
        })
  })
    })
workbox.precaching.precacheAndRoute(self.__precacheManifest || [])

我真的被困在那里,因为工作箱上的所有文档都与利用缓存有关。我正在利用 localforage,因为它支持使离线功能正常工作所需的 Promise。

谢谢

4

1 回答 1

3

您的catch()处理程序需要返回一个Response对象或一个对象的承诺Response

稍微调整示例代码的格式,您当前正在执行以下操作:

.catch(function (error) {
  console.warn(`Constructing a fallback response, due to an error while fetching the real response:, ${error}`)
  localforage.getItem(event.url.pathname).then((res) => {
    let payload = new Response(JSON.stringify(res), { "status" : 200 , "statusText" : "MyCustomResponse!" })
    console.log(payload)
    return payload
  })
})

基于这种格式,我认为更清楚的是,您没有从处理程序中返回 aResponse或 a 的承诺——您根本没有返回任何东西。Responsecatch()

return在您的声明之前添加一个localforage.getItem(...)应该注意这一点:

.catch(function (error) {
  console.warn(`Constructing a fallback response, due to an error while fetching the real response:, ${error}`)
  return localforage.getItem(event.url.pathname).then((res) => {
    let payload = new Response(JSON.stringify(res), { "status" : 200 , "statusText" : "MyCustomResponse!" })
    console.log(payload)
    return payload
  })
})

但是,正如您在原始问题的评论中所提到的,我认为没有必要使用 IndexedDB 来存储这种类型的 URL 可寻址数据。在存储和检索从 HTTP API 获得的 JSON 数据时,您可以只依赖 Cache Storage API,Workbox 默认会愉快地使用它。

于 2018-06-06T18:17:12.643 回答