Cache API: Panduan cepat

Pelajari cara menggunakan Cache API untuk membuat data aplikasi Anda tersedia secara offline.

Cache API adalah sistem untuk menyimpan dan mengambil permintaan jaringan beserta responsnya yang terkait. Ini mungkin berupa permintaan dan respons reguler yang dibuat selama menjalankan aplikasi, atau dapat dibuat hanya untuk tujuan menyimpan data untuk digunakan di lain waktu.

Cache API dibuat untuk memungkinkan pekerja layanan menyimpan permintaan jaringan ke dalam cache sehingga mereka dapat memberikan respons yang cepat, terlepas dari kecepatan atau ketersediaan jaringan. Namun, API ini juga dapat digunakan sebagai mekanisme penyimpanan umum.

Tersedia di mana saja?

Cache API tersedia di semua browser modern. API ini diekspos melalui properti caches global, sehingga Anda dapat menguji keberadaan API dengan deteksi fitur sederhana:

const cacheAvailable = 'caches' in self;

Dukungan Browser

  • 40
  • 16
  • 41
  • 11.1

Sumber

Cache API dapat diakses dari jendela, iframe, worker, atau pekerja layanan.

Apa yang dapat disimpan

Cache hanya menyimpan pasangan objek Request dan Response, yang masing-masing mewakili permintaan dan respons HTTP. Namun, permintaan dan respons dapat berisi segala jenis data yang dapat ditransfer melalui HTTP.

Berapa banyak yang dapat disimpan?

Singkatnya, banyak, setidaknya beberapa ratus megabyte, dan mungkin ratusan gigabyte atau lebih. Implementasi browser bervariasi, tetapi jumlah penyimpanan yang tersedia biasanya didasarkan pada jumlah penyimpanan yang tersedia di perangkat.

Membuat dan membuka cache

Untuk membuka cache, gunakan metode caches.open(name), dengan meneruskan nama cache sebagai parameter tunggal. Jika cache yang diberi nama tidak ada, cache tersebut akan dibuat. Metode ini menampilkan Promise yang di-resolve dengan objek Cache.

const cache = await caches.open('my-cache');
// do something with cache...

Menambahkan ke cache

Ada tiga cara untuk menambahkan item ke cache - add, addAll, dan put. Ketiga metode tersebut menampilkan Promise.

cache.add

Pertama, ada cache.add(). Fungsi ini mengambil satu parameter, Request atau URL (string). Parameter ini membuat permintaan ke jaringan dan menyimpan respons dalam cache. Jika pengambilan gagal, atau jika kode status respons tidak berada dalam rentang 200, tidak ada yang akan disimpan dan Promise akan menolak. Perlu diperhatikan bahwa permintaan lintas origin yang tidak berada dalam mode CORS tidak dapat disimpan karena menampilkan status dari 0. Permintaan tersebut hanya dapat disimpan dengan put.

// Retreive data.json from the server and store the response.
cache.add(new Request('/data.json'));

// Retreive data.json from the server and store the response.
cache.add('/data.json');

cache.addAll

Selanjutnya adalah cache.addAll(). Fungsinya mirip dengan add(), tetapi menggunakan array objek Request atau URL (string). Cara kerjanya mirip dengan memanggil cache.add untuk setiap permintaan, kecuali bahwa Promise akan ditolak jika ada permintaan tunggal yang tidak disimpan dalam cache.

const urls = ['/weather/today.json', '/weather/tomorrow.json'];
cache.addAll(urls);

Pada setiap kasus tersebut, entri baru akan menimpa entri lama yang cocok. Cara ini menggunakan aturan pencocokan yang sama seperti yang dijelaskan di bagian tentang retrieving.

cache.put

Terakhir, ada cache.put(), yang memungkinkan Anda menyimpan respons dari jaringan, atau membuat dan menyimpan Response Anda sendiri. Fungsi ini memerlukan dua parameter. Yang pertama dapat berupa objek Request atau URL (string). Yang kedua harus berupa Response, dari jaringan atau dibuat oleh kode Anda.

// Retrieve data.json from the server and store the response.
cache.put('/data.json');

// Create a new entry for test.json and store the newly created response.
cache.put('/test.json', new Response('{"foo": "bar"}'));

// Retrieve data.json from the 3rd party site and store the response.
cache.put('https://example.com/data.json');

Metode put() lebih permisif daripada add() atau addAll(), dan akan memungkinkan Anda menyimpan respons non-CORS, atau respons lain jika kode status respons tidak berada dalam rentang 200. Tindakan ini akan menimpa respons sebelumnya untuk permintaan yang sama.

Membuat objek Request

Buat objek Request menggunakan URL untuk hal yang disimpan:

const request = new Request('/my-data-store/item-id');

Menangani objek Response

Konstruktor objek Response menerima banyak jenis data, termasuk objek Blob, ArrayBuffer, FormData, dan string.

const imageBlob = new Blob([data], {type: 'image/jpeg'});
const imageResponse = new Response(imageBlob);
const stringResponse = new Response('Hello world');

Anda dapat menetapkan jenis MIME Response dengan menyetel header yang sesuai.

  const options = {
    headers: {
      'Content-Type': 'application/json'
    }
  }
  const jsonResponse = new Response('{}', options);

Jika Anda telah mengambil Response dan ingin mengakses isinya, ada beberapa metode helper yang dapat Anda gunakan. Masing-masing menampilkan Promise yang di-resolve dengan nilai dari jenis berbeda.

Metode Deskripsi
arrayBuffer Menampilkan ArrayBuffer yang berisi isi, yang diserialisasi ke byte.
blob Menampilkan Blob. Jika Response dibuat dengan Blob, Blob baru ini akan memiliki jenis yang sama. Jika tidak, Content-Type dari Response akan digunakan.
text Menafsirkan byte isi sebagai string berenkode UTF-8.
json Menafsirkan byte isi sebagai string berenkode UTF-8, lalu mencoba menguraikannya sebagai JSON. Menampilkan objek yang dihasilkan, atau menampilkan TypeError jika string tidak dapat diurai sebagai JSON.
formData Menafsirkan byte isi sebagai bentuk HTML, yang dienkode sebagai multipart/form-data atau application/x-www-form-urlencoded. Menampilkan objek FormData, atau menampilkan TypeError jika data tidak dapat diurai.
body Menampilkan ReadableStream untuk data isi.

Contoh:

const response = new Response('Hello world');
const buffer = await response.arrayBuffer();
console.log(new Uint8Array(buffer));
// Uint8Array(11) [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]

Mengambil dari cache

Untuk menemukan item dalam cache, Anda dapat menggunakan metode match.

const response = await cache.match(request);
console.log(request, response);

Jika request adalah string, browser akan mengonversinya menjadi Request dengan memanggil new Request(request). Fungsi ini menampilkan Promise yang me-resolve ke Response jika entri yang cocok ditemukan, atau undefined jika tidak.

Untuk menentukan apakah dua Requests cocok, browser menggunakan lebih dari sekadar URL. Dua permintaan dianggap berbeda jika memiliki string kueri, header Vary, atau metode HTTP yang berbeda (GET, POST, PUT, dll.).

Anda dapat mengabaikan beberapa atau semua hal ini dengan meneruskan objek opsi sebagai parameter kedua.

const options = {
  ignoreSearch: true,
  ignoreMethod: true,
  ignoreVary: true
};

const response = await cache.match(request, options);
// do something with the response

Jika lebih dari satu permintaan yang di-cache cocok, permintaan yang dibuat pertama kali akan ditampilkan. Jika ingin mengambil semua respons yang cocok, Anda dapat menggunakan cache.matchAll().

const options = {
  ignoreSearch: true,
  ignoreMethod: true,
  ignoreVary: true
};

const responses = await cache.matchAll(request, options);
console.log(`There are ${responses.length} matching responses.`);

Sebagai pintasan, Anda dapat menelusuri semua cache sekaligus dengan menggunakan caches.match(), bukan memanggil cache.match() untuk setiap cache.

Menelusuri

Cache API tidak menyediakan cara untuk menelusuri permintaan atau respons kecuali untuk entri yang cocok dengan objek Response. Namun, Anda dapat menerapkan penelusuran sendiri menggunakan pemfilteran atau dengan membuat indeks.

Pemfilteran

Salah satu cara untuk menerapkan penelusuran Anda sendiri adalah dengan melakukan iterasi pada semua entri dan memfilter entri ke yang Anda inginkan. Misalkan Anda ingin menemukan semua item yang memiliki URL yang diakhiri dengan .png.

async function findImages() {
  // Get a list of all of the caches for this origin
  const cacheNames = await caches.keys();
  const result = [];

  for (const name of cacheNames) {
    // Open the cache
    const cache = await caches.open(name);

    // Get a list of entries. Each item is a Request object
    for (const request of await cache.keys()) {
      // If the request URL matches, add the response to the result
      if (request.url.endsWith('.png')) {
        result.push(await cache.match(request));
      }
    }
  }

  return result;
}

Dengan cara ini, Anda dapat menggunakan properti objek Request dan Response apa pun untuk memfilter entri. Perhatikan bahwa proses ini lambat jika Anda menelusuri kumpulan data yang besar.

Membuat indeks

Cara lain untuk menerapkan penelusuran Anda sendiri adalah dengan mempertahankan indeks entri terpisah yang dapat ditelusuri dan menyimpan indeks tersebut di IndexedDB. Karena ini adalah jenis operasi yang dirancang untuk IndexedDB, performanya akan jauh lebih baik dengan entri dalam jumlah besar.

Jika Anda menyimpan URL Request bersama dengan properti yang dapat ditelusuri, Anda dapat dengan mudah mengambil entri cache yang benar setelah melakukan penelusuran.

Menghapus item

Untuk menghapus item dari cache:

cache.delete(request);

Ketika permintaan dapat berupa Request atau string URL. Metode ini juga menggunakan objek opsi yang sama seperti cache.match, yang memungkinkan Anda menghapus beberapa pasangan Request/Response untuk URL yang sama.

cache.delete('/example/file.txt', {ignoreVary: true, ignoreSearch: true});

Menghapus cache

Untuk menghapus cache, panggil caches.delete(name). Fungsi ini menampilkan Promise yang me-resolve ke true jika cache sudah ada dan telah dihapus, atau false jika tidak.

Terima kasih

Terima kasih kepada Mat Scales yang menulis versi asli artikel ini, yang pertama kali muncul di WebFundamentals.