Service Worker 可以缓存 POST 请求吗?

新手上路,请多包涵

我试图在获取事件时在服务工作者中缓存 POST 请求。

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

当我尝试访问相同的 POST API 时, caches.match(event.request) 给我未定义。

但是当我对 GET 方法执行相同操作时,它起作用了: caches.match(event.request) GET 请求给了我一个响应。

Service Worker 可以缓存 POST 请求吗?如果他们做不到,我们可以使用什么方法让应用程序真正离线?

原文由 Aniket 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

您不能使用 Cache API 缓存 POST 请求。请参阅 https://w3c.github.io/ServiceWorker/#cache-put (第 4 点)。

规范存储库中有相关讨论: https ://github.com/slightlyoff/ServiceWorker/issues/693

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

原文由 Marco Castelluccio 发布,翻译遵循 CC BY-SA 4.0 许可协议

我在最近的一个带有 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 */
}

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

原文由 A. Kabachnik 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏