Standardmäßig werden Anfragen immer ausgegeben, aber der Browser kann Ergebnisse aus seinem Cache liefern. Um die Verwendung der zwischengespeicherten Ergebnisse zu verbieten, setzen Sie cache auf false. Damit die Anfrage einen Fehler meldet, wenn das Asset seit der letzten Anfrage nicht geändert wurde, setzen Sie ifModified auf true.
Keine dieser Adressen erzwingt jedoch das Caching.
Motivation:
Ich möchte setzen $.ajax({...}) Aufrufe in meinen Initialisierungsfunktionen, von denen einige dieselbe URL anfordern. Manchmal muss ich eine dieser Initialisierungsfunktionen aufrufen, manchmal mehrere.
Ich möchte also die Anfragen an den Server minimieren, wenn diese bestimmte URL bereits geladen wurde.
Ich könnte meine eigene Lösung entwickeln (mit einigen Schwierigkeiten!), aber ich würde gerne wissen, ob es dafür eine Standardmethode gibt.
Ich hätte es nicht für schwierig gehalten, zu verfolgen, welche URLs Sie bereits geladen haben, und die Ergebnisse gegen diese Liste zu speichern. Anschließend können Sie Ihre URLs überprüfen, bevor Sie einen AJAX-Aufruf tätigen. Voila – Sie haben Ihren eigenen Basis-Cache.
– Benutzer1864610
14. Juni 13 um 08:33 Uhr
Sie könnten Ihrer Antwort auf dem Server den Header Cache-Control und Expires hinzufügen, sodass Ihr Server nur nach dem in diesen Werten konfigurierten Timeout aufgerufen werden sollte
– hier und jetzt78
14. Juni 13 um 08:37 Uhr
Es ist sehr lang, aber können Sie mir helfen zu verstehen, warum Sie Cache in Ajax-Anfragen benötigten (möglicherweise in Laiensprache)?
– Asisch
2. November 20 um 9:30 Uhr
TecHunter
cache:true funktioniert nur mit GET- und HEAD-Anfrage.
Sie könnten Ihre eigene Lösung rollen, wie Sie sagten, mit etwas in dieser Richtung:
var localCache = {
data: {},
remove: function (url) {
delete localCache.data[url];
},
exist: function (url) {
return localCache.data.hasOwnProperty(url) && localCache.data[url] !== null;
},
get: function (url) {
console.log('Getting in cache for url' + url);
return localCache.data[url];
},
set: function (url, cachedData, callback) {
localCache.remove(url);
localCache.data[url] = cachedData;
if ($.isFunction(callback)) callback(cachedData);
}
};
$(function () {
var url="/echo/jsonp/";
$('#ajaxButton').click(function (e) {
$.ajax({
url: url,
data: {
test: 'value'
},
cache: true,
beforeSend: function () {
if (localCache.exist(url)) {
doSomething(localCache.get(url));
return false;
}
return true;
},
complete: function (jqXHR, textStatus) {
localCache.set(url, jqXHR, doSomething);
}
});
});
});
function doSomething(data) {
console.log(data);
}
BEARBEITEN: Da dieser Beitrag immer beliebter wird, ist hier eine noch bessere Antwort für diejenigen, die den Timeout-Cache verwalten möchten und sich auch nicht mit dem ganzen Durcheinander in der beschäftigen müssen $.ajax() wie ich benutze $.ajaxPrefilter(). Jetzt nur noch einstellen {cache: true} reicht aus, um den Cache korrekt zu behandeln:
var localCache = {
/**
* timeout for cache in millis
* @type {number}
*/
timeout: 30000,
/**
* @type {{_: number, data: {}}}
**/
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) {
console.log('Getting in cache for url' + 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);
}
};
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.cache) {
var complete = originalOptions.complete || $.noop,
url = originalOptions.url;
//remove jQuery cache as we have our 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="/echo/jsonp/";
$('#ajaxButton').click(function (e) {
$.ajax({
url: url,
data: {
test: 'value'
},
cache: true,
complete: doSomething
});
});
});
function doSomething(data) {
console.log(data);
}
Hier ist eine funktionierende, aber fehlerhafte Implementierung, die mit verzögert arbeitet:
var localCache = {
/**
* timeout for cache in millis
* @type {number}
*/
timeout: 30000,
/**
* @type {{_: number, data: {}}}
**/
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) {
console.log('Getting in cache for url' + 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);
}
};
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.cache) {
//Here is our identifier for the cache. Maybe have a better, safer ID (it depends on the object string representation here) ?
// on $.ajax call we could also set an ID in originalOptions
var id = originalOptions.url+ JSON.stringify(originalOptions.data);
options.cache = false;
options.beforeSend = function () {
if (!localCache.exist(id)) {
jqXHR.promise().done(function (data, textStatus) {
localCache.set(id, data);
});
}
return true;
};
}
});
$.ajaxTransport("+*", function (options, originalOptions, jqXHR, headers, completeCallback) {
//same here, careful because options.url has already been through jQuery processing
var id = originalOptions.url+ JSON.stringify(originalOptions.data);
options.cache = false;
if (localCache.exist(id)) {
return {
send: function (headers, completeCallback) {
completeCallback(200, "OK", localCache.get(id));
},
abort: function () {
/* abort code, nothing needed here I guess... */
}
};
}
});
$(function () {
var url="/echo/jsonp/";
$('#ajaxButton').click(function (e) {
$.ajax({
url: url,
data: {
test: 'value'
},
cache: true
}).done(function (data, status, jq) {
console.debug({
data: data,
status: status,
jqXHR: jq
});
});
});
});
Geige HIER
Bei einigen Problemen ist unsere Cache-ID von der JSON-Objektdarstellung der json2-lib abhängig.
Verwenden Sie die Konsolenansicht (F12) oder FireBug, um einige vom Cache generierte Protokolle anzuzeigen.
Gibt es einen Grund, warum Sie einen Rückruf auf den setzen localCache.set Funktion? Warum nicht einfach doSomehing(jqXHR) nach dem Setzen des Caches?
– kammil
16. Juni 13 um 15:11 Uhr
Ich bevorzuge es einfach so, damit ich so etwas nicht tun muss doSomething(localCache.set(url,jqXHR)); aber es ist nur eine persönliche Vorliebe
– TecHunter
17. Juni 13 um 6:40 Uhr
Irgendwelche Vorschläge zur Verbesserung, um die Verwendung von $.ajax als Versprechen zu unterstützen? Das Zurückgeben von false von beforeSend bricht die Anfrage ab (wie es sollte), sodass vorhandene $.ajax(…).done(function(response) {…}).fail(…) jetzt nicht mehr funktionieren, da fail stattdessen aufgerufen wird als getan … und ich würde sie lieber nicht alle neu schreiben 🙁
– Frank102
6. Juni 14 um 17:42 Uhr
@TecHunter Vielen Dank dafür. Drei weitere geringfügige Verbesserungen könnten vorgenommen werden. Erstens, wenn mehrere Anforderungen gleichzeitig an dieselbe Ressource gestellt werden, verfehlen sie alle den Cache. Um dies zu beheben, möchten Sie möglicherweise den Cache für eine bestimmte “ID” bei der ersten Anfrage auf “Ausstehend” setzen und das Senden von Ergebnissen für nachfolgende Anfragen verschieben, bis die erste zurückkommt. Zweitens möchten Sie möglicherweise das Fehlerergebnis einer Anfrage zwischenspeichern, damit alle Anfragen für dieselbe Ressource dasselbe Ergebnis erhalten.
– mjhm
15. Oktober 14 um 14:08 Uhr
@TecHunter – Schöne Lösung, ich habe diese Lösung mit einer wichtigen Änderung verwendet. Wenn ein zwischengespeichertes Objekt in anderen Funktionen geändert wird, führt dies zu Problemen. Beim Festlegen und Abrufen eines zwischengespeicherten Objekts gebe ich eine Kopie dieses Objekts zurück, die wie unten gezeigt wird: localCache.data[url] = { _: new Date().getTime(), data: _.cloneDeep(cachedData, true) }; _.cloneDeep(localCache.data[url].data, true)
– Bharat Patil
31. März 16 um 4:42 Uhr
immajankmodi
Ich habe nach Caching für meinen Phonegap-App-Speicher gesucht und die Antwort von @TecHunter gefunden, die großartig, aber fertig ist localCache.
Ich habe festgestellt und erfahren, dass localStorage eine weitere Alternative ist, um die von einem Ajax-Aufruf zurückgegebenen Daten zwischenzuspeichern. Also habe ich eine Demo mit erstellt localStorage was anderen helfen wird, die es verwenden möchten localStorage anstatt localCache zum Caching.
Ajax-Aufruf:
$.ajax({
type: "POST",
dataType: 'json',
contentType: "application/json; charset=utf-8",
url: url,
data: '{"Id":"' + Id + '"}',
cache: true, //It must "true" if you want to cache else "false"
//async: false,
success: function (data) {
var resData = JSON.parse(data);
var Info = resData.Info;
if (Info) {
customerName = Info.FirstName;
}
},
error: function (xhr, textStatus, error) {
alert("Error Happened!");
}
});
So speichern Sie Daten in localStorage:
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.cache) {
var success = originalOptions.success || $.noop,
url = originalOptions.url;
options.cache = false; //remove jQuery cache as we have our own localStorage
options.beforeSend = function () {
if (localStorage.getItem(url)) {
success(localStorage.getItem(url));
return false;
}
return true;
};
options.success = function (data, textStatus) {
var responseData = JSON.stringify(data.responseJSON);
localStorage.setItem(url, responseData);
if ($.isFunction(success)) success(responseJSON); //call back to original ajax call
};
}
});
Wenn Sie localStorage entfernen möchten, verwenden Sie die folgende Anweisung, wo immer Sie möchten:
localStorage.removeItem("Info");
Hoffe es hilft anderen!
Hallo, ein localStorage.removeItem("Info");über die "info" ist es die URL?
– Vsogrimen
25. Januar 16 um 2:39 Uhr
@vsogrimen info ist das Objekt zum Speichern der Daten in localStorage.
– immajankmodi
25. Januar 16 um 09:26 Uhr
erhalte weiterhin responseJSON is not defined. Gibt es eine Möglichkeit, dies zu beheben? (Mein Datentyp ist HTML)
– Nikita 웃
6. Februar 16 um 7:21 Uhr
@CreativeMind, entferne reponseJOSN und verwende „var responseData = JSON.stringify( data );“ Machen Sie stattdessen dasselbe mit Erfolg ( data )
– Unico
3. August 17 um 10:05 Uhr
Ich bevorzuge localStorage, da ich Cache für mehrere Anfragen benötigte.
– KeitelDOG
11. März 19 um 17:02 Uhr
Alle modernen Browser bieten Ihnen Speicher-APIs. Sie können sie (localStorage oder sessionStorage) verwenden, um Ihre Daten zu speichern.
Alles, was Sie tun müssen, ist, nachdem Sie die Antwort erhalten haben, sie im Browserspeicher zu speichern. Wenn Sie dann das nächste Mal denselben Anruf finden, suchen Sie, ob die Antwort bereits gespeichert ist. Wenn ja, geben Sie die Antwort von dort zurück; wenn nicht, ruf nochmal an.
Smartjax Das Plugin macht auch ähnliche Dinge; Da Ihre Anforderung jedoch nur das Speichern der Anrufantwort ist, können Sie Ihren Code in Ihre jQuery-Ajax-Erfolgsfunktion schreiben, um die Antwort zu speichern. Und bevor Sie anrufen, prüfen Sie einfach, ob die Antwort bereits gespeichert ist.
Ich habe Antworten in IndexedDB gespeichert, gibt es eine Möglichkeit, IndexedDB zu überprüfen? Wenn ich Sitzungsspeicher verwende, gibt es außerdem eine Möglichkeit, mit jQuery zu überprüfen, ob eine Antwort vorhanden ist oder nicht. Ich kann keine andere Bibliothek als jQuery einbinden. Danke,
– Abhishek Aggarwal
28. März 19 um 8:19 Uhr
Frühling
Wenn ich deine Frage verstanden habe, hier die Lösung:
Wenn Sie das Gegenteil wollen (Cache für bestimmte Anrufe), können Sie am Anfang false und für bestimmte Anrufe true festlegen.
Alte Frage, aber meine Lösung ist etwas anders.
Ich habe eine Single-Page-Web-App geschrieben, die ständig vom Benutzer ausgelöste Ajax-Aufrufe durchführte, und um es noch schwieriger zu machen, waren Bibliotheken erforderlich, die andere Methoden als jquery verwendeten (wie Dojo, natives xhr usw.). Ich habe ein Plugin für eines geschrieben meine eigenen Bibliotheken Ajax-Anfragen so effizient wie möglich zwischenzuspeichern, sodass sie in allen gängigen Browsern funktionieren, unabhängig davon, welche Bibliotheken für den Ajax-Aufruf verwendet wurden.
Die Lösung verwendet jSQL (von mir geschrieben – eine in Javascript geschriebene clientseitige persistente SQL-Implementierung, die indexeddb und andere dom-Speichermethoden verwendet) und mit einer anderen Bibliothek namens gebündelt ist XHRCreep (geschrieben von mir), das eine komplette Neufassung des nativen XHR-Objekts ist.
Um alles zu implementieren, was Sie tun müssen, ist das Plugin in Ihre Seite einzubinden, was hier ist.
Es gibt zwei Möglichkeiten:
jSQL.xhrCache.max_time = 60;
Legen Sie das Höchstalter in Minuten fest. Alle zwischengespeicherten Antworten, die älter sind, werden erneut angefordert. Standard ist 1 Stunde.
jSQL.xhrCache.logging = true;
Wenn dies auf „true“ gesetzt ist, werden Schein-XHR-Aufrufe zum Debuggen in der Konsole angezeigt.
Sie können den Cache auf jeder beliebigen Seite über löschen
jSQL.tables = {}; jSQL.persist();
Ich kann Ihr Plugin in GitHub und auf der offiziellen Website nicht finden. Bitte aktualisieren Sie Ihre Antwort. Ich brauche Ihr Plugin 🙂 Ich bin ein Follower von Ihnen in GitHub. Gute Arbeit 😉 @occams-razor
– Alican Kablan
21. Dezember 18 um 12:21 Uhr
Benutzer1634982
function getDatas() {
let cacheKey = 'memories';
if (cacheKey in localStorage) {
let datas = JSON.parse(localStorage.getItem(cacheKey));
// if expired
if (datas['expires'] < Date.now()) {
localStorage.removeItem(cacheKey);
getDatas()
} else {
setDatas(datas);
}
} else {
$.ajax({
"dataType": "json",
"success": function(datas, textStatus, jqXHR) {
let today = new Date();
datas['expires'] = today.setDate(today.getDate() + 7) // expires in next 7 days
setDatas(datas);
localStorage.setItem(cacheKey, JSON.stringify(datas));
},
"url": "http://localhost/phunsanit/snippets/PHP/json.json_encode.php",
});
}
}
function setDatas(datas) {
// display json as text
$('#datasA').text(JSON.stringify(datas));
// your code here
....
}
// call
getDatas();
Ich kann Ihr Plugin in GitHub und auf der offiziellen Website nicht finden. Bitte aktualisieren Sie Ihre Antwort. Ich brauche Ihr Plugin 🙂 Ich bin ein Follower von Ihnen in GitHub. Gute Arbeit 😉 @occams-razor
– Alican Kablan
21. Dezember 18 um 12:21 Uhr
.
6888300cookie-checkZwischenspeichern einer JQuery-Ajax-Antwort in Javascript/Browseryes
Ich hätte es nicht für schwierig gehalten, zu verfolgen, welche URLs Sie bereits geladen haben, und die Ergebnisse gegen diese Liste zu speichern. Anschließend können Sie Ihre URLs überprüfen, bevor Sie einen AJAX-Aufruf tätigen. Voila – Sie haben Ihren eigenen Basis-Cache.
– Benutzer1864610
14. Juni 13 um 08:33 Uhr
Sie könnten Ihrer Antwort auf dem Server den Header Cache-Control und Expires hinzufügen, sodass Ihr Server nur nach dem in diesen Werten konfigurierten Timeout aufgerufen werden sollte
– hier und jetzt78
14. Juni 13 um 08:37 Uhr
Es ist sehr lang, aber können Sie mir helfen zu verstehen, warum Sie Cache in Ajax-Anfragen benötigten (möglicherweise in Laiensprache)?
– Asisch
2. November 20 um 9:30 Uhr