Heim >Web-Frontend >js-Tutorial >AJAX -AJAX -Cache -Anfragen lokal: Wickeln Sie die Fetch -API ein
Dieser Artikel wurde vom eingeladenen Autor Peter Bengtsson verfasst. SitePoints besonderer Gastbeitrag soll Ihnen großartige Inhalte von bekannten Schriftstellern und Rednern in der JavaScript-Community
bringenDieser Artikel zeigt, wie ein lokaler Cache mit abgerufenen Anforderungen implementiert wird, damit er, wenn er wiederholt ausgeführt wird, aus dem Sitzungsspeicher gelesen wird. Der Vorteil davon ist, dass Sie nicht für jede Ressource benutzerdefinierte Code schreiben müssen, die Sie für einen Zwischenspeichern möchten.
Wenn Sie Ihre nächste JavaScript-Party vorstellen und Ihre verschiedenen Fähigkeiten im Umgang mit Versprechen, hochmodernen APIs und lokalem Speicher zeigen möchten, lesen Sie weiter.
cachedFetch
Kapuliert die Standard -Aufrufe fetch
, die die Antworten automatisch basierend auf Inhaltstyp und URL zwischenspeichern können, wodurch der Cache -Mechanismus universell wird. cachedFetch
enthalten die Handhabung von Cache -Treffern aus dem Sitzungsspeicher vor der Erstellung einer Netzwerkanforderung und die Verwaltung von Inhalten, um veraltete Daten zu vermeiden. Zu diesem Zeitpunkt sollten Sie mit dem Fetch vertraut sein. Es ist eine neue native API im Browser zum Ersetzen der alten XMLHTTPrequest -API.
Wo nicht alle Browser perfekt implementiert sind, können Sie Githubs Fetch -Polyfill verwenden (hier gibt es hier Standardspezifikationen, wenn Sie den ganzen Tag nichts tun).einfache Alternativen
<code class="language-javascript">let origin = null; fetch('https://httpbin.org/get') .then(r => r.json()) .then(information => { origin = information.origin; // 您的客户端IP }); // 需要延迟以确保fetch已完成 setTimeout(() => { console.log('您的来源是 ' + origin); }, 3000);</code>Dies hängt nur von globalen Variablen ab, um zwischengespeicherte Daten zu halten. Das direkte Problem ist, dass, wenn Sie die Seite neu laden oder zu einer neuen Seite navigieren, die zwischengespeicherten Daten verschwinden.
Bevor wir seine Mängel analysieren, aktualisieren wir die erste einfache Lösung.
<code class="language-javascript">fetch('https://httpbin.org/get') .then(r => r.json()) .then(info => { sessionStorage.setItem('information', JSON.stringify(info)); }); // 需要延迟以确保fetch已完成 setTimeout(() => { let info = JSON.parse(sessionStorage.getItem('information')); console.log('您的来源是 ' + info.origin); }, 3000);</code>Das erste direkte Problem ist, dass Fetch auf Versprechen basiert, was bedeutet, dass wir nicht feststellen können, wann es getan wird. Aus Gründen der Gewissheit sollten wir uns also erst auf seine Ausführung verlassen, wenn ihr Versprechen Parsen ist.
Das zweite Problem ist, dass diese Lösung für bestimmte URLs und spezifische zwischengespeicherte Datenausschnitte sehr spezifisch ist (Schlüsselinformationen in diesem Beispiel). Was wir wollen, ist eine universelle URL-basierte Lösung.
Lassen Sie uns einen Wrapper um Fetch erstellen, der ebenfalls ein Versprechen zurückgibt. Der Code, der es aufruft, ist es möglicherweise nicht wichtig, ob das Ergebnis vom Netzwerk oder aus dem lokalen Cache stammt.
Stellen Sie sich vor, Sie haben dies früher gemacht:
<code class="language-javascript">let origin = null; fetch('https://httpbin.org/get') .then(r => r.json()) .then(information => { origin = information.origin; // 您的客户端IP }); // 需要延迟以确保fetch已完成 setTimeout(() => { console.log('您的来源是 ' + origin); }, 3000);</code>codePen Beispiel
Jetzt möchten Sie es einwickeln, damit doppelte Netzwerkanrufe von lokalem Cache profitieren können. Nennen wir es einfach CachedFetch, also sieht der Code so aus:
Wenn es zum ersten Mal ausgeführt wird, muss es die Anfrage über das Netzwerk analysieren und das Ergebnis des Cache speichern. Das zweite Mal sollte direkt aus der lokalen Speicherung extrahiert werden.
<code class="language-javascript">fetch('https://httpbin.org/get') .then(r => r.json()) .then(info => { sessionStorage.setItem('information', JSON.stringify(info)); }); // 需要延迟以确保fetch已完成 setTimeout(() => { let info = JSON.parse(sessionStorage.getItem('information')); console.log('您的来源是 ' + info.origin); }, 3000);</code>
Beginnen wir mit dem Code, der einfach die Fetch -Funktion umhüllt:
<code class="language-javascript">fetch('https://httpbin.org/get') .then(r => r.json()) .then(issues => { console.log('您的来源是 ' + info.origin); });</code>codePen Beispiel
Das funktioniert, aber natürlich funktioniert es nicht. Lassen Sie uns zunächst die Speicherung extrahierter Daten implementieren.
<code class="language-javascript">cachedFetch('https://httpbin.org/get') .then(r => r.json()) .then(info => { console.log('您的来源是 ' + info.origin); });</code>codePen Beispiel
Das erste von Fetch zurückgegebene Versprechen wird die Get -Anfrage tatsächlich weiter ausführen. Wenn es ein Problem mit CORs (Cross-Origin-Ressourcenfreigabe) gibt, funktionieren die Methoden .Text (), .json () oder .blob () nicht.
Das interessanteste Merkmal ist, dass wir das vom erste Versprechen zurückgegebene Antwortobjektklonen müssen. Wenn wir das nicht tun, überinjektieren wir uns selbst, und wenn die Endbenutzer des Versprechens versuchen, .json () (zum Beispiel) zu rufen, erhalten sie diesen Fehler:
Eine andere Sache zu beachten ist die sorgfältige Handhabung des Antworttyps: Wir speichern nur die Antwort, wenn der Statuscode 200 und der Inhaltstyp Anwendung/JSON oder Text/*ist. Dies liegt daran, dass SessionStorage nur Text speichern kann.
Folgendes ist ein Beispiel dafür, wie man es verwendet:<code class="language-javascript">const cachedFetch = (url, options) => { return fetch(url, options); };</code>
Die bisher kluge Sache an dieser Lösung ist, dass es funktioniert, ohne die Anfragen von JSON und
HTML zu stören. Wenn es sich um ein Bild handelt, versucht es nicht, es in SessionStorage zu speichern.zweite Implementierung - Tatsächlicher Rücklauf -Cache -Hit
<code class="language-javascript">const cachedFetch = (url, options) => { // 使用URL作为sessionStorage的缓存键 let cacheKey = url; return fetch(url, options).then(response => { // 让我们只在内容类型为JSON或非二进制内容时存储在缓存中 let ct = response.headers.get('Content-Type'); if (ct && (ct.match(/application\/json/i) || ct.match(/text\//i))) { // 有一个.json()而不是.text(),但我们将它存储在sessionStorage中作为字符串。 // 如果我们不克隆响应,它将在返回时被使用。这样我们就可以不干扰。 response.clone().text().then(content => { sessionStorage.setItem(cacheKey, content); }); } return response; }); };</code>
Daher ist unsere erste Implementierung nur für die Speicherung der Antwort der Anfrage verantwortlich. Wenn Sie jedoch das zweite Mal CachedFetch anrufen, wird es immer noch nicht versuchen, etwas von SessionStorage abzurufen. Was wir tun müssen, ist, ein Versprechen zurückzugeben, und das Versprechen muss ein Antwortobjekt analysieren.
Beginnen wir mit einer sehr grundlegenden Implementierung:codePen Beispiel
es funktioniert!
Um zu sehen, wie es tatsächlich funktioniert, öffnen Sie den Codepen dieses Codes und öffnen Sie dann die Registerkarte "Netzwerk" des Browsers in den Entwickler -Tools. Drücken Sie die Auslauf -Taste ein paar Mal (die obere rechte Ecke von CodePen) und Sie sollten feststellen, dass nur die Bilder wiederholt über das Netzwerk anfordern.
Eine der Klugheiten dieser Lösung ist das Fehlen von "Rückrufnudeln". Da der SessionStorage.GetItem -Anruf synchron ist (d. H. Blockieren), müssen wir uns nicht mit "Ist es in lokaler Speicherung" im Versprechen oder Rückruf zu tun. Und wir werden nur dann zwischengespeicherte Ergebnisse zurückgeben, wenn Inhalte vorhanden sind. Wenn nicht, wird die IF -Anweisung den regulären Code nur weiter ausführen.
Bisher haben wir SessionStorage verwendet, es ist wie LocalStorage, nur dass SessionStorage gelöscht wird, wenn Sie eine neue Registerkarte starten. Dies bedeutet, dass wir eine "natürliche Weise" nutzen, um die Cache -Zeit zu lange zu vermeiden. Wenn wir stattdessen LocalStorage verwenden und etwas zwischenspeichern, wird es dort immer stecken, auch wenn sich der Remote -Inhalt geändert hat, was schlecht ist.
Eine bessere Lösung besteht darin, Benutzer zu kontrollieren. (In diesem Fall ist der Benutzer der Webentwickler, der unsere CachedFetch -Funktion verwendet). Genau wie Memcached oder Redis -Speicher auf der Serverseite können Sie eine Lebensdauer festlegen, die angibt, wie lange es zwischengespeichert werden soll.
Zum Beispiel in Python (mit Flask):
<code class="language-javascript">let origin = null; fetch('https://httpbin.org/get') .then(r => r.json()) .then(information => { origin = information.origin; // 您的客户端IP }); // 需要延迟以确保fetch已完成 setTimeout(() => { console.log('您的来源是 ' + origin); }, 3000);</code>
Jetzt haben weder SessionStorage noch LocalStorage diese Funktion eingebaut, sodass wir sie manuell implementieren müssen. Wir werden dies tun, indem wir den Zeitstempel der gespeicherten Zeit immer anmelden und damit mögliche Cache -Hits vergleichen.
Aber wie wird es aussehen, bevor wir das tun? Zum Beispiel:
<code class="language-javascript">fetch('https://httpbin.org/get') .then(r => r.json()) .then(info => { sessionStorage.setItem('information', JSON.stringify(info)); }); // 需要延迟以确保fetch已完成 setTimeout(() => { let info = JSON.parse(sessionStorage.getItem('information')); console.log('您的来源是 ' + info.origin); }, 3000);</code>
Die wichtigste neue Sache, die wir hinzufügen, ist, dass wir jedes Mal, wenn wir die Antwortdaten speichern, auch aufzeichnen, wenn wenn sie speichern. Bitte beachten Sie jedoch, dass wir jetzt auch zu einer zuverlässigeren Speicherung von LocalStorage anstelle von SessionStorage wechseln können. In unserem benutzerdefinierten abgelaufenen Code wird sichergestellt, dass wir in der anhaltenden lokalen Storage keine sehr veralteten Cache -Hits erhalten. Dies ist also unsere ultimative Arbeitslösung:
<code class="language-javascript">fetch('https://httpbin.org/get') .then(r => r.json()) .then(issues => { console.log('您的来源是 ' + info.origin); });</code>codePen Beispiel
Die Verwirklichung der Zukunft - besser, ausgefallener, cooler
. Es misst andere Dinge, kommt aber im Grunde zu dem Schluss, dass LocalStorage sehr schnell und das Aufwärmen von Scheiben Cache selten ist. Wie verbessern wir unsere Lösungen weiter?
Unsere Implementierung hier kann nicht den Nicht-Text-Inhalt (wie z. B. Bilder) zwischenspeichern, aber es gibt keinen Grund, keinen Zwischenspeicher zu haben. Wir brauchen mehr Code. Insbesondere möchten wir möglicherweise weitere Informationen über den Blob speichern. Jede Antwort ist im Grunde ein Blob. Für Text und JSON ist es nur eine Reihe von Saiten. Typ und Größe spielt keine Rolle, wie Sie aus der Zeichenfolge selbst schließen können. Für binäre Inhalte muss der Blob in einen ArrayBuffer umgewandelt werden.
Für neugierige Personen, um die Implementierungserweiterungen zu sehen, die Bilder unterstützen, überprüfen Sie bitte diesen CodePen: [https://www.php.cn/link/946af3555203AFDB63E571B873E419F6].
Eine weitere potenzielle Verbesserung besteht darin, Platz gegen Geschwindigkeit zu handeln, indem sie jede URL (wir verwenden als Schlüssel), um ihn kleiner zu machen. Im obigen Beispiel verwenden wir nur einige sehr kleine und prägnante URLs (z. B. httpbin.org/get). Wenn Sie jedoch sehr lange URLs haben, gibt es viele Inhalte von Abfragen -Zeichenfolge, und es gibt viele dieser URLs Dann werden sie viel addieren.
Die Lösung für dieses Problem besteht darin, diesen cleveren Algorithmus zu verwenden, der als sicher und schnell angesehen wird:
<code class="language-javascript">let origin = null; fetch('https://httpbin.org/get') .then(r => r.json()) .then(information => { origin = information.origin; // 您的客户端IP }); // 需要延迟以确保fetch已完成 setTimeout(() => { console.log('您的来源是 ' + origin); }, 3000);</code>
Wenn Ihnen dies gefällt, lesen Sie diesen Codepen: [https://www.php.cn/link/946af3555203afdb63e571b873e419f6]. Wenn Sie den Speicher in der Webkonsole überprüfen, sehen Sie einen Schlüssel, der 557027443 ähnelt.
Sie haben jetzt eine funktionierende Lösung, die Sie zu Ihrer Webanwendung hinzufügen können, wo Sie wahrscheinlich die Web -API verwenden, und Sie wissen, dass die Antworten für Ihre Benutzer gut zwischengespeichert werden können.
Das Letzte könnte eine natürliche Erweiterung dieses Prototyps sein, dh ihn über den Artikel hinaus in ein echtes, spezifisches Projekt mit Tests und Readmes und Veröffentlichung auf NPM - aber das muss später gesagt werden!
Caching abgerufene AJAX -Anfragen ist entscheidend für die Verbesserung der Leistung Ihrer Webanwendung. Damit kann der Browser eine Kopie der Serverantwort speichern, damit er nicht die gleiche Anforderung stellen muss. Dies reduziert die Last auf dem Server und beschleunigt die Ladezeit der Webseite, wodurch eine bessere Benutzererfahrung bietet.
Fetch API bietet eine leistungsstarke und flexible Möglichkeit, HTTP -Anforderungen zu stellen. Es enthält einen integrierten Caching-Mechanismus, mit dem Sie angeben können, wie Anforderungen mit dem Cache interagieren sollten. Sie können den Cache-Modus auf "Standard", "No-Store", "Reload", "No-Cache", "Force-Cache" oder "Nur-wenn-Sied" festlegen, jeweils eine unterschiedliche Cache-Steuerung.
Die Fetch -API liefert mehrere Cache -Modi. "Standard" folgt Standard -HTTP -Caching -Regeln. "No-Store" umgeht den Cache vollständig. "Reload" ignoriert zwischengespeicherte Daten und sendet neue Anfragen. "No-Cache" verwendet den Server, um Daten zu überprüfen, bevor die zwischengespeicherte Version verwendet wird. "Force-Cache" verwendet zwischengespeicherte Daten unabhängig von seiner Frische. "Nur-wenn-Sieger" verwendet es nur, wenn die Cache-Daten verfügbar sind, andernfalls schlägt sie fehl.
Sie können Cache in AJAX -Anforderungen implementieren, indem Sie das Cache -Attribut in AJAX -Einstellungen einstellen. Wenn der Browser auf TRUE eingestellt ist, kann der Browser die Antwort zwischenspeichern. Alternativ können Sie die Cache -Optionen der Fetch -API verwenden, um das Verhalten des Cache besser zu steuern.
Um das Caching in AJAX -Anforderungen zu verhindern, können Sie die Cache -Eigenschaft in AJAX -Einstellungen auf false festlegen. Dies zwingt den Browser, seine Reaktion nicht in seinem Cache zu speichern. Alternativ können Sie die Caching-Option "No-Store" der Fetch-API verwenden, um den Cache vollständig zu umgehen.
Während sowohl AJAX- als auch Fetch -APIs Caching -Mechanismen liefern, bietet die Abruf -API eine größere Flexibilität und Kontrolle. Die Cache -Eigenschaft von AJAX ist ein einfacher boolescher Wert, der Cache zulässt oder nicht zulässt. Auf der Cache -Option der Fetch -API können Sie hingegen angeben, wie Anforderungen mit dem Cache interagieren sollten, wodurch Sie eine stärkere Kontrolle erhalten.
Cache kann die Leistung von Webanwendungen erheblich verbessern. Durch das Speichern einer Kopie der Serverantwort muss der Browser nicht die gleiche Anfrage stellen. Dies reduziert die Last auf dem Server und beschleunigt die Ladezeit der Webseite. Der Cache muss jedoch korrekt verwaltet werden, um sicherzustellen, dass Ihre Benutzer den neuesten Inhalt sehen.
Ja, Sie können das Cache -Verhalten einer einzelnen AJAX -Anforderung steuern, indem Sie das Cache -Attribut in den AJAX -Einstellungen für jede Anforderung festlegen. Auf diese Weise können Sie angeben, ob der Browser die Antwort zwischenspeichern sollte.
Das Löschen des von AJAX angeforderten Cache kann durch Einstellen der Cache -Eigenschaft in den AJAX -Einstellungen durchgeführt werden. Dies zwingt den Browser, seine Reaktion nicht in seinem Cache zu speichern. Alternativ können Sie die Option "Reload" -Cache der Fetch -API verwenden, um alle zwischengespeicherten Daten zu ignorieren und neue Anfragen zu senden.
Einige Best Practices für das Zwischenspeichern von AJAX -Anforderungen umfassen: Verständnis verschiedener Cache -Modi und wann Sie verwendet werden, Cache korrekt verwalten, um sicherzustellen, dass Benutzer den neuesten Inhalt sehen und die Cache -Optionen der Fetch -API für eine bessere Kontrolle über Caches verwenden. Bei der Entscheidung für eine Caching -Strategie muss auch die Art der Daten und Benutzererfahrung berücksichtigt werden.
Das obige ist der detaillierte Inhalt vonAJAX -AJAX -Cache -Anfragen lokal: Wickeln Sie die Fetch -API ein. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!