-
-
Save truongluu/84c4c56d8f5e889d96717ca7255a7eb7 to your computer and use it in GitHub Desktop.
Javascript caching fetch data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// From https://www.sitepoint.com/cache-fetched-ajax-requests/ | |
// All credits to: Peter Bengtsson | |
// Added Content-type to headers so it can go to traditional validation like fetch does | |
// Add some debugging messages: activate with { verbose: true } | |
// Add a request to be able to add headers instead of just calling URL | |
const CachedFetch = (url, options) => { | |
let expiry = options.seconds || 5 * 60 // 5 min default | |
let logger = (options.verbose) ? console.log : function(){}; | |
// logger( url, expiry, options); | |
// Use the URL as the cache key to sessionStorage | |
let cacheKey = url | |
let cached = localStorage.getItem(cacheKey) | |
let whenCached = localStorage.getItem(cacheKey + ':ts') | |
if (cached !== null && whenCached !== null) { | |
// it was in sessionStorage! Yay! | |
// Even though 'whenCached' is a string, this operation | |
// works because the minus sign converts the | |
// string to an integer and it will work. | |
let age = (Date.now() - whenCached) / 1000 | |
if (age < expiry) { | |
let response = new Response(new Blob([cached])) | |
response.headers.set("Content-Type","application/json; charset=utf-8") | |
logger("[cachedFetch] Returning cached result"); | |
return Promise.resolve(response) | |
} else { | |
// We need to clean up this old key | |
localStorage.removeItem(cacheKey) | |
localStorage.removeItem(cacheKey + ':ts') | |
} | |
} | |
let request = new Request(url, options.headers) | |
logger("[cachedFetch] loading data", url); | |
return fetch( | |
request | |
).then(response => { | |
logger('[cachedFetch] Response: ', response.headers.get('Content-Type')); | |
// let's only store in cache if the content-type is | |
// JSON or something non-binary | |
if (response.status === 200) { | |
let ct = response.headers.get('Content-Type') | |
if (ct && (ct.match(/application\/json/i) || ct.match(/text\//i))) { | |
// There is a .json() instead of .text() but | |
// we're going to store it in sessionStorage as | |
// string anyway. | |
// If we don't clone the response, it will be | |
// consumed by the time it's returned. This | |
// way we're being un-intrusive. | |
response.clone().text().then(content => { | |
logger('[cachedFetch] Caching '); | |
localStorage.setItem(cacheKey, content) | |
localStorage.setItem(cacheKey+':ts', Date.now()) | |
}) | |
} | |
} | |
logger('[cachedFetch] Returning server response'); | |
return response | |
}) | |
} | |
export default CachedFetch; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import CachedFetch from './CachedFetch.js'; | |
return CachedFetch( | |
yourURL , | |
{ headers: myHeaders, seconds: 5*60, verbose: false } | |
) | |
.then(_verifyResponse, _handleError); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment