服务工作者可以缓存POST请求吗?

Ani*_*ket 21 javascript post request service-worker pwa

我尝试在fetch事件中缓存服务工作者的POST请求.

我用了cache.put(event.request, response),但退回的承诺被拒绝了TypeError: Invalid request method POST..

当我尝试使用相同的POST API时,caches.match(event.request)给了我未定义的内容.

但是当我为GET方法做同样的事情时,它起作用了:caches.match(event.request)因为GET请求给了我一个响应.

服务工作者可以缓存POST请求吗?如果他们不能,我们可以使用什么方法使应用程序真正脱机?

Mar*_*rco 22

您无法使用Cache API缓存POST请求.请参阅https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-put-method(第2.2点).

在规范库中有一个相关的讨论:https://github.com/slightlyoff/ServiceWorker/issues/693

一个有趣的解决方案是ServiceWorker Cookbook中提供 的解决方案:https://serviceworke.rs/request-deferrer.html基本上,该解决方案将请求序列化到IndexedDB.


A. *_*nik 5

我在最近的带有GraphQL API的项目中使用了以下解决方案:我使用请求的序列化表示作为缓存键,将来自API路由的所有响应缓存在IndexedDB对象存储中。然后,如果网络不可用,我将缓存用作后备:

// ServiceWorker.js
self.addEventListener('fetch', function(event) {
    // We will cache all POST requests to matching URLs
    if(event.request.method === "POST" || event.request.url.href.match(/*...*/)){
        event.respondWith(
            // First try to fetch the request from the server
        fetch(event.request.clone())
            // If it works, put the response into IndexedDB
            .then(function(response) {
                // Compute a unique key for the POST request
                var key = getPostId(request);
                // Create a cache entry
                var entry = {
                    key: key,
                    response: serializeResponse(response),
                    timestamp: Date.now()
                };

                /* ... save entry to IndexedDB ... */

                // Return the (fresh) response
                return response;
            })
            .catch(function() {
                // If it does not work, return the cached response. If the cache does not
                // contain a response for our request, it will give us a 503-response
                var key = getPostId(request);
                var cachedResponse = /* query IndexedDB using the key */;
                return response;
            })
        );
    }
})

function getPostId(request) {
    /* ... compute a unique key for the request incl. it's body: e.g. serialize it to a string */
}
Run Code Online (Sandbox Code Playgroud)

这是我使用Dexie.js作为IndexedDB包装器的特定解决方案的完整代码。随意使用它!

  • 尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接的页面发生更改,仅链接的答案可能会失效。-[评论](/ review / low-quality-posts / 20800260) (2认同)