Rumah >hujung hadapan web >tutorial js >Cache diambil Ajax Permintaan Secara Tempatan: Membungkus API Fetch

Cache diambil Ajax Permintaan Secara Tempatan: Membungkus API Fetch

Lisa Kudrow
Lisa Kudrowasal
2025-02-17 11:06:10538semak imbas

Cache Fetched AJAX Requests Locally: Wrapping the Fetch API

Artikel ini ditulis oleh pengarang yang dijemput Peter Bengtsson. Pos tetamu khas SitePoint direka untuk membawa anda kandungan yang hebat dari penulis dan penceramah terkenal dalam komuniti JavaScript

Artikel ini menunjukkan cara melaksanakan cache tempatan permintaan yang diambil supaya jika dilaksanakan berulang kali, ia akan dibaca dari kedai sesi. Manfaat ini ialah anda tidak perlu menulis kod tersuai untuk setiap sumber yang anda mahu cache.

Jika anda ingin memamerkan parti JavaScript seterusnya dan tunjukkan pelbagai kemahiran anda dalam mengendalikan janji, API canggih, dan penyimpanan tempatan, baca terus.

Keuntungan utama

    Menggunakan API Fetch, pemaju boleh membuat cache tempatan permintaan Ajax, meningkatkan kecekapan dengan mengurangkan panggilan rangkaian yang berlebihan dan mempercepatkan pengambilan data.
  • Cara mudah untuk cache menggunakan pembolehubah global adalah terhad oleh ketekunan sesi;
  • Pelaksanaan
  • merangkumi panggilan standard , yang boleh secara automatik boleh memberi maklum balas berdasarkan jenis kandungan dan URL, sehingga menjadikan mekanisme cache universal. cachedFetch Peningkatan ke fetch
  • termasuk pengendalian hits cache dari penyimpanan sesi sebelum membuat permintaan rangkaian, dan menguruskan kandungan tamat tempoh untuk mengelakkan menggunakan data yang sudah lapuk.
  • cachedFetch Penambahbaikan masa depan mungkin termasuk memproses data binari dan menggunakan URL hash sebagai kunci cache untuk mengoptimumkan proses penyimpanan dan pengambilan semula dalam aplikasi web.
  • Ambil API

Pada ketika ini, anda harus akrab dengan Fetch. Ia adalah API asli baru dalam penyemak imbas untuk menggantikan API XMLHTTPREQUEST lama.

Bolehkah saya menggunakan FETCH?

https://www.php.cn/link/b751EA087892EBECA363034301F45C69 Data di laman web mengenai sokongan pelayar utama untuk fungsi Fetch. Di mana tidak semua penyemak imbas dilaksanakan dengan sempurna, anda boleh menggunakan polyfill Github's Fetch (terdapat spesifikasi standard di sini jika anda tidak melakukan apa -apa sepanjang hari).

Alternatif mudah

Katakan anda tahu dengan tepat sumber mana yang anda perlukan untuk memuat turun dan anda hanya mahu memuat turunnya sekali. Anda boleh menggunakan pembolehubah global sebagai cache seperti berikut:

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

Ini hanya bergantung kepada pembolehubah global untuk memegang data cache. Masalah langsung ialah jika anda memuatkan semula halaman atau menavigasi ke halaman baru, data cache akan hilang.

Sebelum kita membedah kelemahannya, mari kita menaik taraf penyelesaian mudah pertama.

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

Masalah langsung pertama ialah pengambilan adalah berdasarkan janji, yang bermaksud kita tidak dapat menentukan kapan ia akan dilakukan, jadi demi kepastian kita tidak harus bergantung pada pelaksanaannya sehingga janjinya.

Masalah kedua ialah penyelesaian ini sangat spesifik untuk URL tertentu dan coretan data cache tertentu (maklumat utama dalam contoh ini). Apa yang kita mahukan ialah penyelesaian berasaskan URL sejagat.

Pelaksanaan Pertama - Pastikan ia mudah

Mari buat pembungkus di sekitar Fetch yang juga mengembalikan janji. Kod yang memanggilnya mungkin tidak peduli sama ada hasilnya dari rangkaian atau dari cache tempatan.

jadi bayangkan anda digunakan untuk melakukan ini:

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

Sekarang anda mahu membungkusnya supaya panggilan rangkaian pendua boleh mendapat manfaat daripada cache tempatan. Mari kita sebut sebagai cache, jadi kodnya kelihatan seperti ini:

<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>
Kali pertama ia berjalan, ia perlu menghuraikan permintaan melalui rangkaian dan menyimpan hasil dalam cache. Kali kedua harus diekstrak terus dari storan tempatan.

mari kita mulakan dengan kod yang hanya membungkus fungsi pengambilan:

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

CODEPEN Contoh

ini berfungsi, tetapi sudah tentu ia tidak berfungsi. Mari kita mula -mula melaksanakan penyimpanan data yang diekstrak.

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

CODEPEN Contoh

Terdapat banyak perkara yang perlu dilakukan di sini.

Janji pertama yang dikembalikan oleh Fetch sebenarnya akan terus melaksanakan permintaan GET. Sekiranya terdapat masalah dengan CORS (perkongsian sumber silang asal), kaedah .text (), .json (), atau .blob () tidak akan berfungsi.

Ciri yang paling menarik ialah kita perlu

mengklon objek tindak balas yang dikembalikan oleh janji pertama. Sekiranya kita tidak, kita mengatasi diri kita sendiri, dan apabila pengguna akhir janji cuba memanggil .json () (contohnya), mereka mendapat kesilapan ini:

Satu lagi perkara yang perlu diperhatikan ialah pengendalian yang berhati -hati terhadap jenis tindak balas: Kami hanya menyimpan respons apabila kod status adalah 200 dan jenis kandungan adalah aplikasi/json atau teks/*. Ini kerana SesiStorage hanya boleh menyimpan teks.

<code class="language-javascript">const cachedFetch = (url, options) => {
  return fetch(url, options);
};</code>
Berikut adalah contoh cara menggunakannya:

Perkara yang bijak mengenai penyelesaian ini setakat ini ialah ia berfungsi tanpa mengganggu permintaan JSON

dan

HTML. Apabila ia adalah imej, ia tidak cuba menyimpannya di 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>
Pelaksanaan Kedua - Cache Pulangan Sebenar Hit

Oleh itu, pelaksanaan pertama kami hanya bertanggungjawab untuk menyimpan respons permintaan tersebut. Walau bagaimanapun, jika anda memanggil CachedFetch untuk kali kedua, ia masih tidak akan cuba untuk mengambil apa -apa dari sessionstorage . Apa yang perlu kita lakukan ialah mengembalikan janji, dan janji perlu menghuraikan objek tindak balas.

mari kita mulakan dengan pelaksanaan yang sangat asas:

CODEPEN Contoh

Ia berfungsi!

Untuk melihat bagaimana ia berfungsi, buka codepen kod ini dan kemudian buka tab "Rangkaian" pelayar dalam alat pemaju. Tekan butang Run beberapa kali (sudut kanan atas Codepen) dan anda harus melihat bahawa hanya imej yang meminta berulang kali melalui rangkaian.

Salah satu kepandaian penyelesaian ini ialah kekurangan "pasta panggil balik". Sejak Panggilan SesiStorage.GetItem adalah segerak (iaitu menyekat), kita tidak perlu berurusan dengan "Adakah dalam simpanan tempatan?" Dan kami akan mengembalikan hasil cache hanya jika terdapat kandungan. Jika tidak, pernyataan IF hanya akan terus melaksanakan kod biasa.

Pelaksanaan ketiga - bagaimana dengan masa tamat?

Setakat ini kami telah menggunakan SesiStorage, ia seperti LocalStorage, hanya sessionStorage yang dibersihkan apabila anda memulakan tab baru. Ini bermakna kita memanfaatkan "cara semulajadi" untuk mengelakkan masa cache terlalu lama. Sekiranya kita menggunakan localStorage dan cache sesuatu, ia akan sentiasa terjebak di sana walaupun kandungan terpencil telah berubah, yang buruk.

Penyelesaian yang lebih baik adalah untuk membiarkan pengguna kawalan. (Dalam kes ini, pengguna adalah pemaju web yang menggunakan fungsi cache kami). Sama seperti penyimpanan memcached atau redis di sisi pelayan, anda boleh menetapkan seumur hidup yang menentukan berapa lama ia harus di -cache.

Sebagai contoh, dalam Python (menggunakan 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>

Sekarang, SesiStorage atau LocalStorage tidak mempunyai ciri ini, jadi kita perlu melaksanakannya secara manual. Kami akan melakukan ini dengan sentiasa melayari timestamp masa yang disimpan dan menggunakannya untuk membandingkan kemungkinan cache hits.

Tetapi bagaimana rupa sebelum kita melakukan ini? Contohnya:

<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>
perkara baru yang akan kami tambahkan ialah setiap kali kami menyimpan data tindak balas, kami juga akan merakam apabila

apabila menyimpannya. Tetapi sila ambil perhatian bahawa sekarang kita juga boleh beralih ke penyimpanan LocalStorage yang lebih dipercayai dan bukannya SesiStorage. Kod tamat tempoh kami akan memastikan kami tidak mendapat hits cache yang sangat basi di LocalStorage yang berterusan. Jadi ini adalah penyelesaian kerja utama kami:

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

realisasi masa depan - lebih baik, lebih mewah, sejuk

Bukan sahaja kita mengelakkan lebih daripada API web ini, bahagian yang terbaik adalah bahawa LocalStorage jauh lebih cepat daripada rangkaian yang bergantung. Sila rujuk kepada catatan blog ini untuk perbandingan LocalStorage vs XHR:

Localforage vs. XHR

. Ia mengukur perkara lain, tetapi pada dasarnya menyimpulkan bahawa LocalStorage sangat cepat dan pemanasan cache cakera jarang berlaku.

Jadi bagaimana kita terus memperbaiki penyelesaian kita?

memproses tindak balas binari

Pelaksanaan kami di sini tidak cache kandungan bukan teks (seperti imej), tetapi tidak ada sebab untuk tidak cache. Kami memerlukan lebih banyak kod. Khususnya, kami mungkin mahu menyimpan lebih banyak maklumat mengenai gumpalan itu. Setiap tindak balas pada dasarnya adalah gumpalan. Untuk teks dan JSON, ia hanya pelbagai rentetan. Jenis dan saiz tidak penting, kerana anda boleh menyimpulkan dari rentetan itu sendiri. Untuk kandungan binari, gumpalan mesti ditukar kepada arraybuffer.

Bagi orang yang ingin tahu, untuk melihat sambungan pelaksanaan yang menyokong imej, sila periksa codepen ini: [https://www.php.cn/link/946af35555503afdb63e571b873e419f6].

Gunakan kunci cache hash

Satu lagi peningkatan potensi adalah untuk perdagangan ruang untuk kelajuan dengan hashing setiap URL (kami menggunakan sebagai kunci) untuk menjadikannya lebih kecil. Dalam contoh di atas, kami hanya menggunakan beberapa URL yang sangat kecil dan ringkas (mis. Httpbin.org/get), tetapi jika anda mempunyai URL yang sangat panjang, terdapat banyak kandungan rentetan pertanyaan, dan terdapat banyak URL ini , maka mereka akan menambah banyak.

Penyelesaian masalah ini adalah menggunakan algoritma pintar ini, yang dianggap selamat dan cepat:

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

Jika anda suka ini, lihat codepen ini: [https://www.php.cn/link/946af35555203afdb63e571b873e419f6]. Jika anda menyemak storan di konsol web, anda akan melihat kunci yang serupa dengan 557027443.

Kesimpulan

Anda kini mempunyai penyelesaian kerja yang boleh anda tambahkan ke aplikasi web anda, di mana anda mungkin menggunakan API Web dan anda tahu bahawa respons boleh di -cache dengan baik untuk pengguna anda.

Perkara terakhir mungkin merupakan lanjutan semulajadi prototaip ini, iaitu, untuk menggerakkannya di luar artikel, menjadi projek yang nyata dan khusus dengan ujian dan readmes dan menerbitkannya pada NPM - tetapi yang tersisa untuk dikatakan kemudian!

Soalan Lazim Mengenai Permintaan Ajax yang Diekstrak Cached (FAQ)

Apakah kepentingan caching yang diambil permintaan AJAX?

Caching mengambil permintaan AJAX adalah penting untuk meningkatkan prestasi aplikasi web anda. Ia membolehkan penyemak imbas menyimpan salinan respons pelayan supaya ia tidak perlu membuat permintaan yang sama sekali lagi. Ini mengurangkan beban pada pelayan dan mempercepatkan masa pemuatan laman web, dengan itu memberikan pengalaman pengguna yang lebih baik.

Bagaimanakah API Fetch berfungsi dengan cache?

Ambil API menyediakan cara yang kuat dan fleksibel untuk membuat permintaan HTTP. Ia termasuk mekanisme caching terbina dalam yang membolehkan anda menentukan bagaimana permintaan harus berinteraksi dengan cache. Anda boleh menetapkan mod cache kepada "lalai", "no-store", "Reload", "no-cache", "force-cache", atau "only-if-cakret", masing-masing dengan tahap kawalan cache yang berbeza.

Apakah mod cache yang berbeza dalam API Fetch dan apa maksudnya?

API Fetch menyediakan beberapa mod cache. "Lalai" mengikuti peraturan caching HTTP standard. "No-Store" memintas cache sepenuhnya. "Reload" mengabaikan sebarang data cache dan menghantar permintaan baru. "No-Cache" menggunakan pelayan untuk mengesahkan data sebelum menggunakan versi cache. "Force-cache" menggunakan data cache tanpa mengira kesegarannya. "Hanya-jika-cache" hanya menggunakannya apabila data cache tersedia, jika tidak, ia gagal.

Bagaimana untuk melaksanakan cache dalam permintaan Ajax?

anda boleh melaksanakan cache dalam permintaan AJAX dengan menetapkan atribut cache dalam tetapan AJAX. Jika ditetapkan kepada Benar, ia akan membolehkan penyemak imbas untuk cache respons. Sebagai alternatif, anda boleh menggunakan pilihan cache API FETCH untuk mengawal kelakuan cache yang lebih baik.

Bagaimana untuk mengelakkan cache dalam permintaan Ajax?

Untuk mengelakkan caching dalam permintaan AJAX, anda boleh menetapkan sifat cache dalam tetapan Ajax ke FALSE. Ini akan memaksa penyemak imbas untuk tidak menyimpan responsnya dalam cache. Sebagai alternatif, anda boleh menggunakan pilihan caching "No-Store" untuk API Fetch untuk memintas cache sepenuhnya.

Apakah perbezaan antara caching di Ajax dan Ambil API?

Walaupun kedua -dua Ajax dan mengambil API menyediakan mekanisme caching, API Fetch memberikan fleksibiliti dan kawalan yang lebih besar. Harta cache Ajax adalah nilai boolean yang mudah yang membolehkan atau tidak membenarkan cache. Sebaliknya, pilihan cache API Fetch membolehkan anda menentukan bagaimana permintaan harus berinteraksi dengan cache, memberikan anda lebih banyak kawalan berbutir.

Bagaimanakah caching mempengaruhi prestasi aplikasi web saya?

Cache dapat meningkatkan prestasi aplikasi web dengan ketara. Dengan menyimpan salinan respons pelayan, penyemak imbas tidak perlu membuat permintaan yang sama sekali lagi. Ini mengurangkan beban pada pelayan dan mempercepatkan masa pemuatan laman web. Walau bagaimanapun, cache mesti diuruskan dengan betul untuk memastikan pengguna anda melihat kandungan terkini.

Bolehkah saya mengawal tingkah laku cache permintaan AJAX tunggal?

Ya, anda boleh mengawal tingkah laku cache permintaan AJAX tunggal dengan menetapkan atribut cache dalam tetapan AJAX untuk setiap permintaan. Ini membolehkan anda menentukan sama ada penyemak imbas harus cache respons.

Bagaimana untuk membersihkan cache permintaan Ajax?

Mengosongkan cache yang diminta oleh Ajax boleh dilakukan dengan menetapkan harta cache kepada palsu dalam tetapan Ajax. Ini akan memaksa penyemak imbas untuk tidak menyimpan responsnya dalam cache. Sebagai alternatif, anda boleh menggunakan pilihan cache "Reload" untuk API Fetch untuk mengabaikan sebarang data cache dan menghantar permintaan baru.

Apakah beberapa amalan terbaik untuk permintaan Ajax caching?

Beberapa amalan terbaik untuk permintaan Ajax caching termasuk: Memahami mod cache yang berbeza dan bila menggunakannya, menguruskan cache dengan betul untuk memastikan pengguna melihat kandungan terkini, dan menggunakan pilihan cache API Fetch untuk kawalan yang lebih baik ke atas cache. Apabila memutuskan strategi caching, sifat data dan pengalaman pengguna juga mesti dipertimbangkan.

Atas ialah kandungan terperinci Cache diambil Ajax Permintaan Secara Tempatan: Membungkus API Fetch. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn