-
-
Save javisperez/4bb09e0437994a659bbcd06f90eeebbf to your computer and use it in GitHub Desktop.
| // Usually I use this in my app's config file, in case I need to disable all cache from the app | |
| // Cache is from `js-cache`, something like `import Cache from 'js-cache';` | |
| const cacheable = true, | |
| cache = new Cache(); | |
| // On request, return the cached version, if any | |
| axios.interceptors.request.use(request => { | |
| // Only cache GET requests | |
| if (request.method === 'get' && cacheable) { | |
| let url = request.url; | |
| // Append the params, I use jquery param but you can change to whatever you use | |
| if (request.params) | |
| url += '?' + $.param(request.params); | |
| const _cached = cache.get(url); | |
| if (_cached) { | |
| _cached.__fromCache = true; | |
| console.log(`"${url}" served from cache:`, _cached); | |
| request.data = _cached; | |
| // Set the request adapter to send the cached response and prevent the request from actually running | |
| request.adapter = () => { | |
| return Promise.resolve({ | |
| data: _cached, | |
| status: request.status, | |
| statusText: request.statusText, | |
| headers: request.headers, | |
| config: request, | |
| request: request | |
| }); | |
| }; | |
| } | |
| } | |
| return request; | |
| }, error => Promise.reject(error)); | |
| // On response, set or delete the cache | |
| axios.interceptors.response.use(response => { | |
| // if you dont want to cache a specific url, send a param `__cache = false` | |
| const isCacheable = !response.config.params || (response.config.params && response.config.params.__cache !== false); | |
| if (cacheable && isCacheable) { | |
| let url = response.config.url; | |
| if (response.config.params) | |
| url += '?' + $.param(response.config.params); | |
| if (response.config.method === 'get') { | |
| // On get request, store the response in the cache | |
| cache.set(url, response.data); | |
| } else { | |
| // For post, put or delete, just delete the cached version of the url | |
| // e.g. posting to `/users` would delete the `/users` cache, so when you ask for users again you get the real version | |
| cache.del(response.config.url); | |
| // also, when making a post,put or delete request to `/users/1`, would try to delete the `/users` for the same reason | |
| const uri = url.replace(config.http.api.base_url, ''), | |
| parentUri = /(.*)\/([a-z0-9\-]+)\/?$/ig.exec(uri); | |
| if (parentUri) | |
| cache.del(`${config.http.api.base_url}${parentUri[1]}`); | |
| // Delete similar url that just have query string diferences | |
| // Specially useful for things like Laravel's `with` param | |
| // e.g. `/users?with=permissions` will get cached but the post to `/users` wont remove it from the cache | |
| // so I look all the cached url's and try to match it without the querystrings | |
| const urls = Object.keys(cache.debug()); | |
| for (const _url of urls) { | |
| if (_url.match(/^[^?]+/)[0] === response.config.url) | |
| cache.del(_url); | |
| } | |
| } | |
| } | |
| return response; | |
| }, error => Promise.reject(error)); |
Awesome man, this saved my day trying terminate axios request when I already have the cached version
Good example! A while ago i started with something like that and ended up with my own small library.
If anyone wants to try it out: axios-cache-interceptor
Here's an example:
import axios from 'axios';
import { setupCache } from 'axios-cache-interceptor';
setupCache(axios);
const req1 = axios.get('https://api.example.com/');
const req2 = axios.get('https://api.example.com/');
const [res1, res2] = await Promise.all([req1, req2]);
res1.cached // false
res2.cached // true@arthurfiorette
I have tried it, it's so cool!!! But I have a question about buildMemoryCache's useful, that after I reload the page, and request the prev API URL cached before. My expectation is that request will get from the memory cache, but it actually makes a new request again (TTL still valid). Is my knowledge wrong with the docs? (https://axios-cache-interceptor.js.org/#/pages/storages)
Hey, the memory storage does what it is capable of, when you reload a page any variable is erased. What you want to do is use web storages as described in the docs too.
Great job! I was looking for how to terminate original request from network! Thanks!