Saeed Amin
Saeed Amin

Reputation: 165

NUXT-PWA to cache the POST request

I'm using NUXT-PWA to cache my data but I have a page that depend on a POST request to be build and I need to cache the respond which is JSON but I get the error below:

Uncaught (in promise) attempt-to-cache-non-get-request: Unable to cache '/api/hotel/order/get-voucher' because it is a 'POST' request and only 'GET' requests can be cached.

the code I use in my workbox-range-request.js is this:

workbox.routing.registerRoute(
  new RegExp('/api/(.*)'),
  new workbox.strategies.CacheFirst({
    cacheName: 'apiCache',
    plugins: [
      new workbox.expiration.Plugin({
        maxEntries: 100,
        maxAgeSeconds: 7 * 24 * 60 * 60, // 7 Days
      }),
    ],
  }),
  'POST'
); 

and my nuxt.config.js :

  workbox: {
    dev:true,
    cachingExtensions: '@/plugins/workbox-range-request.js',
    runtimeCaching: [
      {
        urlPattern: 'https://www.google-analytics.com/.*',
        handler: 'StaleWhileRevalidate',
        method: 'GET',
        strategyOptions: { cacheableResponse: { statuses: [0, 200] } }
      }
    ]
  },

in document says it support the POST but in console I got the error and in my cacheStore I got no data.

Upvotes: 0

Views: 2190

Answers (1)

Jeff Posnick
Jeff Posnick

Reputation: 56044

The Cache Storage API prevents you from using a POST request as the key when saving an entry. This is due, in part, because a POST request is "traditionally" something that's actually sent to a server to make changes to remote state, and in that model, fulfilling that via a local cached response without ever reach the server doesn't make sense.

But... let's say that you do get meaningful data back in the response body after sending a POST request, and you want to save that response body using the Cache Storage API, using a GET request with a potentially different URL as the cache key.

You can do that using Workbox via a cacheKeyWillBeUsed custom plugin:

const savePostResponsePlugin = {
  cacheKeyWillBeUsed: async ({request, mode}) => {
    if (mode === 'write') {
      // Use the same URL as `POST` request as the cache key.
      // Alternatively, use a different URL.
      return request.url;
    }
  },
};

workbox.routing.registerRoute(
  new RegExp('/api/(.*)'),
  new workbox.strategies.CacheFirst({
    cacheName: 'apiCache',
    plugins: [
      // Add the custom plugin to your strategy.
      savePostResponsePlugin,
      new workbox.expiration.Plugin({...}),
    ],
  }),
  'POST'
);

This is not something that I'd recommend doing unless you're specifically sure that you want to save the POST response bodies in the cache for a good reason.

If you're just looking for a way of resending the POST requests when an initial attempt fails because you're offline, I'd recommend using workbox-background-sync instead.

Upvotes: 1

Related Questions