Может ли Workbox помочь мне распаковать данные с разбивкой на страницы в кеш?

Скажем, у меня есть архитектура RESTful для сообщений в блогах:

  • /api/blogs?from=0&to=30 will return me 30 posts.
    • /api/blogs/page/1 would return me the same 30 posts.
  • /api/post/13 вернет содержание сообщения в блоге № 13.

Предполагая, что форма объекта сообщения более или менее одинакова между этими двумя конечными точками REST, вы можете разумно предположить, что содержимое из /api/post/13 будет включено в содержимое из /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, внутренний для стратегии workbox для маршрута /api/blogs, возвращает undefined.

Я думаю, что мне не хватает чего-то важного, возможно, о том, как cache.match используется Workbox, или о том, как объекты запроса / ответа используются в API кеша, или о предположениях, которые я делаю о том, как работают обращения к кешу, или обо всех выше. Я просто еще не уверен, что это такое. У кого-нибудь есть мысли?


person Chris    schedule 23.04.2018    source источник


Ответы (1)


Оказалось, что это проблема CORS. Поскольку я делал запрос к удаленному экземпляру, мне нужно было создать запрос с полным URL вместо корневого. Как только я это сделал, все заработало, как и ожидалось.

person Chris    schedule 28.04.2018