Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get axios-cache-adapter to cache file downloads with responseType blob?

For some reason axios-cache-adapter is not caching GET requests for file downloads which I believe is due to setting responseType: 'blob' (as I don't have caching issues on other requests that don't require this field be set as such) which is required for axios to generate the src url(as per this answer):

src: URL.createObjectURL(new Blob([response.data])),

My adapter setup is as follows:

// set axios defaults
axios.defaults.headers.common = {
  'Authorization': `Bearer ${accessToken}`,
  'Content-Type': 'application/json'
};

const configureAxios = async () => {

  await localforage.defineDriver(memoryDriver);

  const forageStore = localforage.createInstance({
    driver: [
      localforage.INDEXEDDB,
      localforage.LOCALSTORAGE,
      memoryDriver._driver
    ],
    name: 'my-cache'
  });

  return setup({

    // `axios-cache-adapter` options
    cache: {
      maxAge: 15 * 60 * 1000,
      exclude: {
        query: false
      },
      store: forageStore,
    }
  });
};

// call this function in JSX Component to download file
export const downloadFile = async (fileId) => {
  const api = await configureAxios();

  const response = await api.get(`api/download/${fileId}`, {
    responseType: 'blob',
  });

  return response.data; // returns file data
};

Your help would be much appreciated.

like image 433
MShakeG Avatar asked Sep 05 '21 20:09

MShakeG


1 Answers

@D-Money pointed me in the right direction. So basically axios-cache-adapter v3 fixes the issue of not caching requests with responseType blob or arraybuffers, however it's currently only available in beta so you'll have to install that as follows in the interim:

npm install axios-cache-adapter@beta

Then you'll have to make a slight adjustment by setting readHeaders: false, in the axios-cache-adapter options in setup and additionally move the axios default config directly into setup, which in my case results in the following net changes:

const configureAxios = async () => {

  await localforage.defineDriver(memoryDriver);

  const forageStore = localforage.createInstance({
    driver: [
      localforage.INDEXEDDB,
      localforage.LOCALSTORAGE,
      memoryDriver._driver
    ],
    name: 'my-cache'
  });

  return setup({

    // Options passed to `axios.create()` method
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },

    // `axios-cache-adapter` options
    cache: {
      readHeaders: false,
      maxAge: 15 * 60 * 1000,
      exclude: {
        query: false
      },
      store: forageStore,
    }
  });
};

// call this function in JSX Component to download file
export const downloadFile = async (fileId) => {
  const api = await configureAxios();

  const response = await api.get(`api/download/${fileId}`, {
    responseType: 'blob',
  });

  return response.data; // returns file data
};

like image 153
MShakeG Avatar answered Sep 27 '22 00:09

MShakeG