1

假设我有一个用于博客文章的 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.matchWorkbox 是如何使用的,或者请求/响应对象如何在缓存 API 中使用,或者关于我对缓存命中如何工作的假设,或者以上所有. 我只是不确定它是什么。有人有想法吗?

4

1 回答 1

0

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

于 2018-04-28T13:11:56.760 回答