工作箱可以帮我解析分页数据到缓存吗?

时间:2018-04-23 14:04:23

标签: workbox

假设我有一个用于博客帖子的RESTful架构:

  • /api/blogs?from=0&to=30会给我30个帖子。
    • /api/blogs/page/1会给我回复30个帖子。
  • /api/post/13将返回博客文章#13的内容。

假设post对象的形状在这两个REST端点之间或多或少相同,那么您可以合理地假设来自/api/post/13的内容将包含在/api/blogs/page/1的内容中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

我认为我遗漏了一些重要的东西,可能是关于Workbox如何使用cache.match,或者如何在缓存API中使用请求/响应对象,或者关于如何缓存我的假设点击工作,或以上所有。我只是不确定它到底是什么。有人有想法吗?

1 个答案:

答案 0 :(得分:0)

这证明是CORS的一个问题。由于我向远程实例发出请求,因此我需要使用完全限定的URL而不是根相对的URL创建请求。一旦我这样做,这就按预期工作了。