ホームページ >ウェブフロントエンド >jsチュートリアル >キャッシュFETCED AJAXリクエストはローカルにリクエストします。フェッチAPIをラップします

キャッシュFETCED AJAXリクエストはローカルにリクエストします。フェッチAPIをラップします

Lisa Kudrow
Lisa Kudrowオリジナル
2025-02-17 11:06:10529ブラウズ

Cache Fetched AJAX Requests Locally: Wrapping the Fetch API

この記事は、招待された著者ピーター・ベンツソンによって書かれました。 SitePointの特別ゲスト投稿は、JavaScriptコミュニティの有名な作家やスピーカーから素晴らしいコンテンツを提供するように設計されています

この記事では、フェッチされたリクエストのローカルキャッシュを実装する方法を示しているため、セッションストアから繰り返し実行されると読み取られます。これの利点は、キャッシュするすべてのリソースのカスタムコードを記述する必要がないことです。

次のJavaScriptパーティーを披露し、約束、最先端のAPI、およびローカルストレージを処理するためのさまざまなスキルを披露したい場合は、読み続けてください。

メインゲイン

  • Fetch APIを使用して、開発者はAjaxリクエストのローカルキャッシュを作成し、冗長ネットワーク呼び出しを削減し、データ検索を高速化することで効率を改善できます。
  • グローバル変数を使用してキャッシュする簡単な方法は、セッションストレージに切り替えることで、同じセッションの持続性のページにわたってリロードできます。
  • 実装cachedFetch標準の呼び出しをカプセル化します。これは、コンテンツの種類とURLに基​​づいて応答を自動的にキャッシュでき、キャッシュメカニズムを普遍的にします。 fetch
  • の拡張機能には、ネットワークリクエストを行う前にセッションストレージからキャッシュヒットを処理すること、および古いデータの使用を避けるためにコンテンツの管理が期限切れになります。 cachedFetch
  • 将来の改善には、バイナリデータの処理と、Webアプリケーションのストレージと検索プロセスを最適化するためのキャッシュキーとしてハッシュURLを使用することが含まれます。
Fetch API

この時点で、フェッチに精通している必要があります。これは、古いxmlhttprequest APIを置き換えるためのブラウザの新しいネイティブAPIです。

fetch?https://www.php.cn/link/b751ea087892ebeca363034301f45c69フェッチ機能に対する主要なブラウザーのサポートに関するウェブサイトのデータ。

すべてのブラウザが完全に実装されているわけではない場合、GithubのFetch PolyFillを使用できます(一日中何もしていない場合は、ここにはフェッチ標準仕様があります)。

単純な代替品

ダウンロードする必要があるリソースを正確に知っていると仮定し、1回だけダウンロードする必要があるとします。グローバル変数を次のようにキャッシュとして使用できます。

<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例

これは、キャッシュされたデータを保持するためのグローバル変数にのみ依存します。直接的な問題は、ページをリロードしたり、新しいページに移動したりすると、キャッシュされたデータが消えることです。

その欠点を分析する前に、最初の簡単なソリューションをアップグレードしましょう。

<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>
CODEPEN例

最初の直接的な問題は、フェッチが約束に基づいていることです。つまり、いつ行われるかを判断できないため、確実性のために、約束が除いてその実行に依存してはなりません。

2番目の問題は、このソリューションが特定のURLと特定のキャッシュデータスニペットに非常に固有であることです(この例の重要な情報)。私たちが望むのは、ユニバーサルURLベースのソリューションです。

最初の実装 - シンプルに保ちます

フェッチを返すラッパーの周りにラッパーを作成しましょう。それを呼び出すコードは、結果がネットワークからであるかローカルキャッシュからであるかを気にしないかもしれません。

それで、あなたがこれを行うのに使用していたと想像してください:

<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例

これで、ネットワーク呼び出しを複製できるように、ローカルキャッシュの恩恵を受けることができます。 cachedfetchと呼んでみましょう。そうすれば、コードは次のようになります。

最初に実行されたとき、ネットワーク上で要求を解析し、結果をキャッシュに保存する必要があります。 2回目は、ローカルストレージから直接抽出する必要があります。

<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>
フェッチ機能をラップする単純なコードから始めましょう:

CODEPEN例
<code class="language-javascript">fetch('https://httpbin.org/get')
  .then(r => r.json())
  .then(issues => {
    console.log('您的来源是 ' + info.origin);
  });</code>

これは機能しますが、もちろん機能しません。最初に抽出されたデータのストレージを実装しましょう。

CODEPEN例
<code class="language-javascript">cachedFetch('https://httpbin.org/get')
  .then(r => r.json())
  .then(info => {
    console.log('您的来源是 ' + info.origin);
  });</code>

ここにはたくさんのことがあります。

Fetchによって返された最初の約束は、実際にGet Requestを実行し続けます。 CORS(クロスオリジンリソース共有)に問題がある場合、.text()、.json()、または.blob()メソッドは機能しません。

最も興味深い機能は、最初の約束によって返された応答オブジェクトをクローンする必要があることです。そうでない場合、私たちは自分自身を挿入し、約束のエンドユーザーが.json()を呼び出すようにしようとするとき、彼らはこのエラーを取得します:

注意すべきもう1つのことは、応答タイプの慎重な処理です。ステータスコードが200

の場合のみ、コンテンツタイプがアプリケーション/jsonまたはテキスト/*である場合にのみ回答を保存します。これは、SessionStorageがテキストのみを保存できるためです。

以下は、それを使用する方法の例です。 これまでのこのソリューションについての巧妙なことは、JSON

および
<code class="language-javascript">const cachedFetch = (url, options) => {
  return fetch(url, options);
};</code>
HTMLリクエストを妨害することなく機能することです。それが画像である場合、それはセッションストレージに保存しようとはしません。

2回目の実装 - 実際のリターンキャッシュがヒット したがって、最初の実装は、リクエストの応答を保存する責任のみを担当します。ただし、CachedFetchを2回目に呼び出すと、SessionStorage

から何も取得しようとはしません。私たちがする必要があるのは、約束を返すことであり、約束は応答オブジェクトを解析する必要があります。

非常に基本的な実装から始めましょう:
<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>

CODEPEN例

動作します!

実際にどのように機能するかを確認するには、このコードのCodepenを開き、開発者ツールでブラウザの[ネットワーク]タブを開きます。実行ボタンを数回押し(Codepenの右上隅)、画像のみがネットワーク上で繰り返し要求していることがわかります。

このソリューションの賢さの1つは、「コールバックパスタ」の欠如です。 sessionstorage.getItemコールは同期(つまり、ブロック)であるため、「ローカルストレージでは」と対処する必要はありません。また、コンテンツがある場合にのみ、キャッシュされた結果を返します。そうでない場合、IFステートメントは通常のコードのみを実行し続けます。

3番目の実装 - 有効期限はどうですか?

これまでのところ、sessionstorageを使用しています。これはLocalStorageのようなものです。新しいタブを開始すると、SessionStorageがクリアされています。これは、キャッシュ時間が長すぎるのを避けるために「自然な方法」を活用していることを意味します。代わりにLocalStorageを使用して何かをキャッシュすると、リモートコンテンツが変更されていても、常にそこに詰まってしまいます。これは悪いことです。

より良い解決策は、

ユーザーを制御することです。 (この場合、ユーザーはcachedfetch関数を使用するWeb開発者です)。サーバー側のmemcachedまたはredisストレージと同様に、キャッシュする時間を指定する寿命を設定できます。 たとえば、

Python(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>
今、SessionStorageもLocalStorageもこの機能を組み込んでいないため、手動で実装する必要があります。これは、保存された時間のタイムスタンプを常にログに記録し、それを使用して可能なキャッシュヒットを比較することで行います。

しかし、これを行う前にそれはどのように見えますか?たとえば、

<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>
追加する重要な新しいことは、応答データを保存するたびに、

を保存したときに記録することです。ただし、SessionStorageの代わりにLocalStorageのより信頼性の高いストレージに切り替えることもできます。カスタムの期限切れのコードにより、永続的なローカルストレージで非常に古いキャッシュヒットが得られないようにします。 これが私たちの究極の実用的なソリューションです:

CODEPEN例
<code class="language-javascript">fetch('https://httpbin.org/get')
  .then(r => r.json())
  .then(issues => {
    console.log('您的来源是 ' + info.origin);
  });</code>

未来の実現 - より良い、より派手、クール

これらのWeb APIの過剰アクセスを避けるだけでなく、最良の部分は、LocalStorageが従属ネットワークよりもはるかに高速であることです。 LocalStorageとXHR:

Localforage vs. XHR

の比較については、このブログ投稿を参照してください。他のことを測定しますが、基本的にはLocalStorageが非常に高速であり、ディスクキャッシュのウォームアップはまれであると結論付けています。

では、どのようにしてソリューションをさらに改善するのでしょうか?

バイナリ応答の処理

ここでの実装は、非テキストコンテンツ(画像など)をキャッシュしませんが、キャッシュしない理由はありません。もっとコードが必要です。特に、BLOBに関する詳細情報を保存したい場合があります。各応答は基本的にブロブです。テキストとJSONの場合、それは単なる文字列です。文字列自体から推測できるため、タイプとサイズは重要ではありません。バイナリ含有量の場合、BLOBはArrayBufferに変換する必要があります。

好奇心が強い人々のために、画像をサポートする実装拡張機能を表示するには、このCodepenを確認してください:[https://www.php.cn/link/946af3555203afdb63e571b873e419f6]。

ハッシュキャッシュキーを使用します

もう1つの潜在的な改善は、各URL(キーとして使用)をハッシュして小さくすることにより、スペースを速度と交換することです。上記の例では、非常に小さく簡潔なURL(httpbin.org/getなど)のみを使用していますが、非常に長いURLがある場合は、文字列コンテンツがたくさんあり、これらのURLがたくさんあります。 、その後、彼らは多くのことになります。

この問題の解決策は、この巧妙なアルゴリズムを使用することです。これは安全かつ高速と見なされます。

これが好きなら、このCodepen:[https://www.php.cn/link/946af3555203afdb63e571b873e419f6]をチェックしてください。 Webコンソールのストレージを確認すると、557027443に似たキーが表示されます。
<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>

結論

Webアプリケーションに追加できる作業ソリューションがあります。おそらくWeb APIを使用しているため、ユーザーにとって応答が適切にキャッシュできることがわかります。

最後のことは、このプロトタイプの自然な拡張、つまり、記事を超えて、テストとreadmesを使用して実際の特定のプロジェクトに移動し、NPMで公開することかもしれませんが、後で言われるべきです!

キャッシュされた抽出されたajax要求(FAQ)

に関する

FAQ

フェッチしたajaxリクエストのキャッシュの重要性は何ですか?

キャッシュフェッチしたAJAXリクエストは、Webアプリケーションのパフォーマンスを改善するために重要です。これにより、ブラウザがサーバーの応答のコピーを保存できるため、同じリクエストを再度作成する必要がなくなります。これにより、サーバーの負荷が削減され、Webページの読み込み時間が高速化され、ユーザーエクスペリエンスが向上します。

フェッチAPIはキャッシュでどのように動作しますか?

Fetch APIは、HTTPリクエストを作成するための強力で柔軟な方法を提供します。これには、リクエストがキャッシュと対話する方法を指定できる組み込みのキャッシュメカニズムが含まれています。キャッシュモードを「デフォルト」、「ノーストア」、「リロード」、「ノーキャッシュ」、「フォースキャッシュ」、または「キャッシュのみ」に設定できます。それぞれがキャッシュコントロールのレベルが異なります。

フェッチAPIのさまざまなキャッシュモードは何ですか?それはどういう意味ですか?

Fetch APIには、いくつかのキャッシュモードが提供されます。 「デフォルト」は、標準のHTTPキャッシングルールに従います。 「ストアなし」はキャッシュを完全にバイパスします。 「リロード」はキャッシュされたデータを無視し、新しいリクエストを送信します。 「No-Cache」は、キャッシュバージョンを使用する前にサーバーを使用してデータを確認します。 「Force-Cache」は、新鮮さに関係なくキャッシュデータを使用します。 「キャッシュされていない場合」は、キャッシュデータが利用可能な場合にのみ使用しますが、それ以外の場合は失敗します。

ajaxリクエストにキャッシュを実装する方法は?

Ajax設定でCache属性を設定することにより、Ajaxリクエストにキャッシュを実装できます。 Trueに設定すると、ブラウザが応答をキャッシュできます。または、フェッチAPIのキャッシュオプションを使用して、キャッシュの動作をよりよく制御できます。

ajaxリクエストでキャッシュを防ぐ方法は?

Ajaxリクエストでのキャッシュを防ぐために、Ajax設定のキャッシュプロパティをFalseに設定できます。これにより、ブラウザは応答をキャッシュに保存しないようにします。または、フェッチAPIの「ストアなし」キャッシュオプションを使用して、キャッシュを完全にバイパスすることもできます。

AjaxとFetch APIのキャッシュの違いは何ですか?

AjaxとFetch APIの両方がキャッシュメカニズムを提供しますが、Fetch APIはより柔軟性と制御を提供します。 Ajaxのキャッシュプロパティは、キャッシュを許可または許可しない単純なブール値です。一方、Fetch APIのキャッシュオプションを使用すると、リクエストがキャッシュと対話する方法を指定して、より詳細な制御を可能にします。

キャッシングは私のWebアプリケーションのパフォーマンスにどのように影響しますか?

キャッシュは、Webアプリケーションのパフォーマンスを大幅に改善できます。サーバーの応答のコピーを保存することにより、ブラウザは同じリクエストを再度行う必要はありません。これにより、サーバーの負荷が削減され、Webページの読み込み時間が高速化されます。ただし、ユーザーが最新のコンテンツを確認するために、キャッシュを正しく管理する必要があります。

単一のAJAX要求のキャッシュ動作を制御できますか?

はい、各リクエストのAJAX設定にキャッシュ属性を設定することにより、単一のAJAX要求のキャッシュ動作を制御できます。これにより、ブラウザが応答をキャッシュするかどうかを指定できます。

ajaxリクエストのキャッシュをクリアする方法は?

Ajaxによって要求されたキャッシュのクリアのクリアは、AJAX設定でCacheプロパティをFalseに設定することで実行できます。これにより、ブラウザは応答をキャッシュに保存しないようにします。または、フェッチAPIの「リロード」キャッシュオプションを使用して、キャッシュされたデータを無視して新しいリクエストを送信することもできます。

キャッシュAJAXリクエストのベストプラクティスは何ですか?

キャッシュAJAXリクエストのベストプラクティスには、さまざまなキャッシュモードとそれらを使用するタイミングの理解、ユーザーが最新のコンテンツを確認するためにキャッシュを正しく管理し、キャッシュをより適切に制御できるようにフェッチAPIのキャッシュオプションを使用することが含まれます。キャッシュ戦略を決定する場合、データとユーザーエクスペリエンスの性質も考慮する必要があります。

以上がキャッシュFETCED AJAXリクエストはローカルにリクエストします。フェッチAPIをラップしますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。