来自 IDB 而不是缓存的工作箱离线响应
workbox offline response from IDB instead of cache
我正在使用 service worker 构建一个 vueJs 应用程序。我决定使用带有 InjestManifest 方法的 Workbox 来拥有我自己的路线。
在线时获取:
1- 用网络回答
2- 将正文写入 IDB(通过 localforage)
3- 发回响应
此处一切正常,sw 截取获取并返回适当的响应,IDB 包含正确的详细信息。
在线时发送回 fecth 的响应:
响应{type: "cors", url: "http://localhost:3005/api/events", redirected: false, status: 200, ok: true, ...}
问题出在我离线时。
我的意图是连接到 Locaforage 并检索内容并建立响应。
问题是 Fetch 认为此响应不合适,然后拒绝它。 Console.log 确认 sw 中的 .catch 正在工作,但看起来它发送的响应被拒绝了。
这是我在离线时发回以获取的响应的 console.log;
响应 {type: "default", url: "", redirected: false, status: 200, ok: true, ...}
我不知道 fetch 是否不满意,因为响应的 url 与请求中的不同,但 workbox 应该允许使用来自缓存或 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,因为它支持承诺,这是使离线功能正常工作所必需的。
谢谢
您的 catch()
处理程序需要 return 一个 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
})
})
根据这种格式,我认为您不是 return在您的 catch()
中 Response
或 Response
的承诺更清楚handler—你根本没有 returning 任何东西。
在 localforage.getItem(...)
语句之前添加 return
应该可以解决这个问题:
.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-addressable 数据。在存储和检索从 HTTP API.
获取的 JSON 数据时,您可以只依赖缓存存储 API,Workbox 默认会愉快地使用它
我正在使用 service worker 构建一个 vueJs 应用程序。我决定使用带有 InjestManifest 方法的 Workbox 来拥有我自己的路线。
在线时获取: 1- 用网络回答 2- 将正文写入 IDB(通过 localforage) 3- 发回响应
此处一切正常,sw 截取获取并返回适当的响应,IDB 包含正确的详细信息。 在线时发送回 fecth 的响应: 响应{type: "cors", url: "http://localhost:3005/api/events", redirected: false, status: 200, ok: true, ...}
问题出在我离线时。 我的意图是连接到 Locaforage 并检索内容并建立响应。 问题是 Fetch 认为此响应不合适,然后拒绝它。 Console.log 确认 sw 中的 .catch 正在工作,但看起来它发送的响应被拒绝了。 这是我在离线时发回以获取的响应的 console.log; 响应 {type: "default", url: "", redirected: false, status: 200, ok: true, ...}
我不知道 fetch 是否不满意,因为响应的 url 与请求中的不同,但 workbox 应该允许使用来自缓存或 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,因为它支持承诺,这是使离线功能正常工作所必需的。
谢谢
您的 catch()
处理程序需要 return 一个 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
})
})
根据这种格式,我认为您不是 return在您的 catch()
中 Response
或 Response
的承诺更清楚handler—你根本没有 returning 任何东西。
在 localforage.getItem(...)
语句之前添加 return
应该可以解决这个问题:
.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-addressable 数据。在存储和检索从 HTTP API.
获取的 JSON 数据时,您可以只依赖缓存存储 API,Workbox 默认会愉快地使用它