example - ¿Cuáles son las posibles técnicas para almacenar en caché una respuesta Ajax en Javascript?
use strict es6 (5)
¿Otra respuesta específica de JQUERY?
No estoy seguro de que responda a su pregunta, pero eso podría ayudar. Es cachear las llamadas ajax con un tiempo de espera.
En el prefiltrado, enumere las diversas llamadas ajax de PHP que desea agregar para el almacenamiento en caché. En este ejemplo, la memoria caché se habilita con un tiempo de espera de 10 minutos.
/*----------------------------*/
/* set ajax caching variables */
/*----------------------------*/
$.set_Ajax_Cache_filters = function () {
var localCache = {
timeout: 600000, // 10 minutes
data: {}, //@type {{_: number, data: {}}}
remove: function (url) {
delete localCache.data[url];
},
exist: function (url) {
return !!localCache.data[url] && ((new Date().getTime() - localCache.data[url]._) < localCache.timeout);
},
get: function (url) {
return localCache.data[url].data;
},
set: function (url, cachedData, callback) {
localCache.remove(url);
localCache.data[url] = {
_: new Date().getTime(),
data: cachedData
};
if ($.isFunction(callback))
callback(cachedData);
}
};
/*----------------------*/
/* set ajax pre filters */
/*----------------------*/
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
// list of allowed url to cache
if (url !== ''..............file.php'') {
return false;
}
if (options.cache) {
var complete = originalOptions.complete || $.noop,
url = originalOptions.url;
options.cache = false;//remove jQuery cache using proprietary one
options.beforeSend = function () {
if (localCache.exist(url)) {
complete(localCache.get(url));
return false;
}
return true;
};
options.complete = function (data, textStatus) {
localCache.set(url, data, complete);
};
}
});
};
Estoy implementando un administrador de módulos de Javascript que carga archivos javascript a través del objeto XHR
. El problema de este método es el almacenamiento en caché de recursos:
- En primer lugar,
XHR
depende del mecanismo de almacenamiento en caché del navegador incorporado, que está bien, pero su comportamiento depende de la implementación del navegador. - También hay un
localStorage
y hay un basket.js que usalocalStorage
para almacenar en caché los scripts descargados, el problema está en el tamaño limitado de almacenamiento, que suele ser de 5-10 MB. Además, localStorage es un lugar compartido para muchos scripts que también lo utilizan para almacenar datos. - Y hay una interfaz de
Cache
de la API deServiceWorker
, pero está disponible solo en el tiempo de ejecución deServiceWorker
por lo que sin duda se ajusta a mis necesidades.
¿Alguien sabe alguna técnica inteligente antigua o nueva de almacenamiento en caché de javascript que esté usando en su proyecto, o que haya escuchado?
Nota : Por favor, no proponga utilizar jQuery .ajax
que es una interfaz para XHR
, o cualquier otra biblioteca que implemente una interfaz para las funciones de JavaScript incorporadas.
Edit : ha habido algunas propuestas valiosas:
- Utilice la biblioteca llamada localForage. La biblioteca representa una API unificada para IndexedDB, WebSQL y localStorage, la cual se usa depende del navegador.
- Utilice IndexedDB, que es un almacenamiento verdaderamente potente sin límites de espacio significativos. La única preocupación es que solo los navegadores modernos implementan IndexedDB.
Dado que indexeddb es un método utilizado para almacenar datos del lado del cliente, permite consultas de bases de datos indexadas.
Y estos son los navegadores compatibles http://caniuse.com/#feat=indexeddb
Y estos son los únicos problemas.
Firefox (prior to version 37) and Safari do not support IndexedDB inside web workers.
Not supported in Chrome for iOS or other iOS WebViews.
Chrome 36 and below did not support Blob objects as indexedDB values.
Aquí hay otro polyfill similar que puede probar , pero en mi experiencia (aunque limitada), ambos polyfills están buggy / incompletos. Ambos también tienen muchos problemas abiertos en GitHub de personas que reportan problemas. Y cuando probé uno de ellos (olvido cuál) fue significativamente más lento que el IndexedDB nativo.
Tal vez es posible crear un polyfill decente, pero los actuales no parecen estar haciendo el trabajo.
¿Debo usar WebSQL que estaba en desuso?
El problema con WebSQL es que nunca será compatible con IE o Firefox. Probablemente podría salirse con el WebSQL si solo está apuntando a los navegadores móviles, al menos hasta que Firefox OS o Windows Phone obtengan una cuota de mercado significativa.
¿Hay planes para admitir IndexedDB en el futuro para todos los navegadores no compatibles?
Seamos claros. Pregunta por Apple, ya que todos los demás admiten IndexedDB en su último navegador (iOS Chrome usa el motor de renderizado de Apple porque Apple no les permitirá hacer nada más).
Apple no solo no es compatible con IndexedDB, sino que no han dicho públicamente nada al respecto (por lo que puedo decir ... y he hecho una gran cantidad de búsquedas). Lo que parece bastante raro. Entonces, lo mejor que puedo decir, nadie tiene idea de si Apple alguna vez planea apoyar a IndexedDB. El teórico de la conspiración en mí piensa que tal vez intentan sabotear las aplicaciones HTML5 para forzar a las personas a escribir aplicaciones nativas, pero eso es pura especulación.
En total, esto nos deja a los desarrolladores en una situación bastante mala. No hay una buena solución multiplataforma. Le recomiendo que se queje con Apple al respecto. Eso es lo que hice y les pedí a mis usuarios que quieren usar mi aplicación basada en IndexedDB en iOS que hagan lo mismo. Todavía no hay noticias de Apple.
ACTUALIZACIÓN: Indexeddb ahora es compatible con iOS 8 como se indicó en la WWDC 2014, pero desafortunadamente está muy mal .
Teniendo en cuenta también que la integridad del sub - recurso -
Subresource Integrity permite a los navegadores verificar que el archivo se entrega sin manipulación inesperada.
¿No tiene conocimientos? hasta aquí ?
Te sugeriré que puedas ir con
Solución basada en sub-recursos si el móvil es su objetivo principal
indexeddb si el dispositivo móvil no es su objetivo principal y el uso de las implementaciones disponibles públicamente para dispositivos móviles
Si todo lo anterior suena demasiado complejo para ti, entonces
var localCache = {
data: {},
remove: function (url) {
delete localCache.data[url];
},
//a cached version exists
exist: function (url) {
return !!localCache.data[url] && ((new Date().getTime() - localCache.data[url]._) < localCache.timeout);
},
get: function (url) {
console.log(''Getting in cache for url'' + url); //log only!
return localCache.data[url].data;
},
set: function (url, cachedData, callback) {
localCache.remove(url);
localCache.data[url] = {
_: new Date().getTime(),
data: cachedData
};
if ($.isFunction(callback)) callback(cachedData);
},
timeout: 600, //in seconds
};
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.cache) {
var complete = originalOptions.complete || $.noop,
url = originalOptions.url;
//remove jQuery cache as you have your own localCache
options.cache = false;
options.beforeSend = function () {
if (localCache.exist(url)) {
complete(localCache.get(url));
return false;
}
return true;
};
options.complete = function (data, textStatus) {
localCache.set(url, data, complete);
};
}
});
$(function () {
var url = ''your url goes here'';
$(''#ajaxButton'').click(function (e) {
$.ajax({
url: url,
data: {
test: ''value''
},
cache: true,
complete: doSomething
});
});
});
//ToDo after ajax call finishes, or cached version retrived
function doSomething(data) {
console.log(data);
}
Esto es específico para JQUERY ....
Puedes configurar ajax como caché.
$.ajaxSetup({ cache: true});
y si para llamadas específicas no quiere hacer una respuesta en caché, llame
$.ajax({
url: ...,
type: "GET",
cache: false,
...
});
Si desea lo contrario (caché para llamadas específicas) puede establecer falso al principio y verdadero para llamadas específicas
Si desea almacenar el resultado de la respuesta ajax, puede hacer uso del almacenamiento local. Todos los navegadores modernos le proporcionan apis de almacenamiento. Puede usarlos (localStorage o sessionStorage) para guardar sus datos.
Todo lo que tiene que hacer es después de recibir la respuesta almacenarla en el almacenamiento del navegador. Luego, la próxima vez que encuentre la misma llamada, busque si la respuesta ya está guardada. Si es así, devuelve la respuesta desde allí; Si no hace una nueva llamada.
El plugin Smartjax también hace cosas similares; pero como su requisito es simplemente guardar la respuesta de la llamada, puede escribir su código dentro de la función de éxito de jQuery ajax para guardar la respuesta. Y antes de hacer una llamada, compruebe si la respuesta ya está guardada.
Intenta esto podría funcionar
var cache = {};
var formatTweets(info) {
//formats tweets, does whatever you want with the tweet information
};
//event
$(''myForm'').addEvent(''submit'',function() {
var handle = $(''handle'').value; //davidwalshblog, for example
var cacheHandle = handle.toLowerCase();
if(cache[cacheHandle] != "undefined") {
formatTweets(cache[cacheHandle]);
}
else {
//gitter
var myTwitterGitter = new TwitterGitter(handle,{
count: 10,
onComplete: function(tweets,user) {
cache[cacheHandle] = tweets;
formatTweets(tweets);
}
}).retrieve();
}
});
Para hacer esto, la mejor técnica es usar la opción de caché local, ajaxPrefilter y ajax, la combinación de estos tres te creará el caché sólido que deseas, que puedes controlar fácilmente. Aquí hay un ejemplo de código:
var localCache = {
data: {},
remove: function (url) {
delete localCache.data[url];
},
//a cached version exists
exist: function (url) {
return !!localCache.data[url] && ((new Date().getTime() - localCache.data[url]._) < localCache.timeout);
},
get: function (url) {
console.log(''Getting in cache for url'' + url); //log only!
return localCache.data[url].data;
},
set: function (url, cachedData, callback) {
localCache.remove(url);
localCache.data[url] = {
_: new Date().getTime(),
data: cachedData
};
if ($.isFunction(callback)) callback(cachedData);
},
timeout: 600, //in seconds
};
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.cache) {
var complete = originalOptions.complete || $.noop,
url = originalOptions.url;
//remove jQuery cache as you have your own localCache
options.cache = false;
options.beforeSend = function () {
if (localCache.exist(url)) {
complete(localCache.get(url));
return false;
}
return true;
};
options.complete = function (data, textStatus) {
localCache.set(url, data, complete);
};
}
});
$(function () {
var url = ''your url goes here'';
$(''#ajaxButton'').click(function (e) {
$.ajax({
url: url,
data: {
test: ''value''
},
cache: true,
complete: doSomething
});
});
});
//ToDo after ajax call finishes, or cached version retrived
function doSomething(data) {
console.log(data);
}