Can service workers cache POST requests? Can service workers cache POST requests? javascript javascript

Can service workers cache POST requests?


You can't cache POST requests using the Cache API. See https://w3c.github.io/ServiceWorker/#cache-put (point 4).

There's a related discussion in the spec repository: https://github.com/slightlyoff/ServiceWorker/issues/693

An interesting solution is the one presented in the ServiceWorker Cookbook: https://serviceworke.rs/request-deferrer.htmlBasically, the solution serializes requests to IndexedDB.


I've used the following solution in a recent project with a GraphQL API: I cached all responses from API routes in an IndexedDB object store using a serialized representation of the Request as cache key. Then I used the cache as a fallback if the network was unavailable:

// ServiceWorker.jsself.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 */}

Here is the full code for my specific solution using Dexie.js as IndexedDB-wrapper. Feel free to use it!


If you are talking about form data, then you could intercept the fetch event and read the form data in a similar way as below and then save the data in indexedDB.

//service-worker.jsself.addEventListener('fetch', function(event) {      if(event.request.method === "POST"){         var newObj = {};               event.request.formData().then(formData => {                for(var pair of formData.entries()) {                  var key = pair[0];                  var value =  pair[1];                  newObj[key] = value;                }              }).then( ...save object in indexedDB... )      }})