假设我有一个用于博客文章的 RESTful 架构:
/api/blogs?from=0&to=30
将返回我 30 个帖子。/api/blogs/page/1
会给我同样的 30 个帖子。
/api/post/13
将返回博客文章 #13 的内容。
假设 post 对象的形状在这两个 REST 端点之间或多或少相同,您可以合理地假设内容 from/api/post/13
将包含在 from 的内容中/api/blogs/page/1
。
在这个用例中,我试图解析这些分页响应并使用它们来为各个帖子预热缓存。
如果我自己编写缓存,我只会为 创建一个缓存blogs
,并且每次我请求其中的一页时,我都会遍历响应并根据需要向缓存中添加一些内容:
function oncePaginatedResultsFetched(jsonResults) {
caches.open('blogs-cache').then(cache => {
jsonResults.forEach(result => cache.put(`/api/blog/${result.id}`, result))
});
}
这可以很好地填充缓存。
我发现,当我在使用 Workbox 时尝试类似的事情时,各种开箱即用的策略都找不到我已推送到缓存中的这些项目。
workbox.routing.registerRoute(
//api\/post\/(\d+)/,
workbox.strategies.cacheFirst({
cacheName: "posts"
}),
"GET"
);
workbox.routing.registerRoute(
//api\/blogs/,
workbox.strategies.staleWhileRevalidate({
cacheName: "blog-page-list",
plugins: [{
// Take the collection of items returned in the list response, then individually
// cache each item in the collection.
// This is ... almost certainly a hack around workbox.
// todo: set appropriate cache + date headers in the request and response objects.
cachedResponseWillBeUsed: babelHelpers.asyncToGenerator(
function* ({ cacheName, request, matchOptions, cachedResponse }) {
const newResponse = cachedResponse.clone();
const data = yield cachedResponse.json();
if (data) {
const cache = yield caches.open("posts");
for (let i = 0, ii = data.length; i < ii; i++) {
let item = data[i];
let body = JSON.stringify(item);
let res = new Response(body, {
headers: new Headers({
'Content-Type': 'application/json',
'Content-Length': body.length,
'Date': new Date().toUTCString(),
})
});
yield cache.put(`/api/post/${item.id}`, res);
}
}
return newResponse;
}
),
}]
}),
"GET"
);
当我运行它时,chrome 的 devtools 告诉我cache.match
调用内部到工作箱的/api/blogs
路由返回策略的策略undefined
。
我想我遗漏了一些重要的东西,可能是关于cache.match
Workbox 是如何使用的,或者请求/响应对象如何在缓存 API 中使用,或者关于我对缓存命中如何工作的假设,或者以上所有. 我只是不确定它是什么。有人有想法吗?