Cache API: Hızlı bir kılavuz

Uygulama verilerinizi çevrimdışı olarak kullanılabilir hale getirmek için Cache API'yi nasıl kullanacağınızı öğrenin.

Cache API, ağ isteklerini ve bunlara karşılık gelen yanıtları depolayıp almak için kullanılan bir sistemdir. Bunlar, uygulamanızın çalışması sırasında oluşturulan normal istek ve yanıtlar ya da yalnızca daha sonra kullanmak üzere verileri depolamak amacıyla oluşturulmuş olabilir.

Cache API, hizmet işçilerinin ağ hızından veya kullanılabilirliğinden bağımsız olarak hızlı yanıtlar sunabilmeleri için ağ isteklerini önbelleğe almalarını sağlamak amacıyla oluşturulmuştur. Ancak API, genel bir depolama mekanizması olarak da kullanılabilir.

Nerelerde kullanılabilir?

Cache API, tüm modern tarayıcılarda kullanılabilir. API, global caches mülkü aracılığıyla kullanıma sunulur. Bu nedenle, basit bir özellik algılamayla API'nin varlığını test edebilirsiniz:

const cacheAvailable = 'caches' in self;

Tarayıcı desteği

  • Chrome: 40.
  • Edge: 16.
  • Firefox: 41.
  • Safari: 11.1.

Kaynak

Cache API'ye bir pencereden, iFrame'den, çalışandan veya hizmet çalışanından erişilebilir.

Depolanabilecek içerikler

Önbellekler yalnızca Request ve Response nesne çiftlerini, sırasıyla HTTP isteklerini ve yanıtlarını temsil eder. Ancak istekler ve yanıtlar, HTTP üzerinden aktarılabilen her tür veriyi içerebilir.

Ne kadar veri depolanabilir?

Kısacası, büyük miktarda, en az birkaç yüz megabayt ve potansiyel olarak yüzlerce gigabayt veya daha fazla boyut. Tarayıcı uygulamaları değişiklik gösterir ancak kullanılabilir depolama alanı genellikle cihazdaki kullanılabilir depolama alanına bağlıdır.

Önbelleğe alma alanı oluşturma ve açma

Bir önbelleği açmak için caches.open(name) yöntemini kullanın ve tek parametre olarak önbelleğin adını iletin. Adlandırılmış önbellek mevcut değilse oluşturulur. Bu yöntem, Cache nesnesi ile çözüldüğünde bir Promise döndürür.

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

Önbelleğe alma

Bir öğeyi önbelleğe eklemenin üç yolu vardır: add, addAll ve put. Her üç yöntem de Promise döndürür.

cache.add

İlk sırada cache.add() var. Bir Request veya URL (string) parametresi alır. Ağa istek gönderir ve yanıtı önbellekte depolar. Getirme başarısız olursa veya yanıtın durum kodu 200 aralığında değilse hiçbir şey depolanmaz ve Promise reddeder. CORS modunda olmayan kaynak arası isteklerin, 0 türünde bir status döndürdükleri için depolanamayacağını unutmayın. Bu tür istekler yalnızca put ile depolanabilir.

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

Ardından cache.addAll() var. add() işlevine benzer şekilde çalışır ancak bir dizi Request nesnesi veya URL'si (string) alır. Bu işlem, her istek için cache.add çağrılmasına benzer şekilde çalışır. Tek bir istek önbelleğe alınmazsa Promise ise isteği reddeder.

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

Bu durumların her birinde, yeni bir giriş, eşleşen mevcut girişlerin üzerine yazılır. Bu işlemde, getirme bölümünde açıklanan eşleme kuralları kullanılır.

cache.put

Son olarak, ağdan bir yanıt depolamanıza veya kendi Response'unuzu oluşturup depolamanıza olanak tanıyan cache.put() vardır. İki parametre alır. İlki bir Request nesnesi veya URL (string) olabilir. İkincisi, ağdan veya kodunuz tarafından oluşturulan bir Response olmalıdır.

// 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');

put() yöntemi, add() veya addAll() yönteminden daha serbesttir ve CORS olmayan yanıtları veya yanıtın durum kodunun 200 aralığında olmadığı diğer yanıtları depolamanıza olanak tanır. Aynı istek için önceki yanıtların üzerine yazılır.

Request nesneleri oluşturma

Depolanan öğenin URL'sini kullanarak Request nesnesini oluşturun:

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

Yanıt nesneleriyle çalışma

Response nesne kurucusu; Blob, ArrayBuffer, FormData nesneleri ve dizeler dahil birçok veri türünü kabul eder.

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

Uygun üstbilgiyi ayarlayarak Response öğesinin MIME türünü ayarlayabilirsiniz.

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

Bir Response aldıysanız ve mesajın gövdesine erişmek istiyorsanız kullanabileceğiniz birkaç yardımcı yöntem vardır. Her biri farklı türde bir değerle çözüldüğünde Promise döndürür.

Yöntem Açıklama
arrayBuffer Baytlara serileştirilmiş gövdeyi içeren bir ArrayBuffer döndürür.
blob Bir Blob döndürür. Response, Blob ile oluşturulduysa bu yeni Blob aynı türe sahiptir. Aksi takdirde, Response öğesinin Content-Type değeri kullanılır.
text Gövdenin baytlarını UTF-8 ile kodlanmış bir dize olarak yorumlar.
json Gövdenin baytlarını UTF-8 olarak kodlanmış dize olarak yorumlar ve ardından JSON olarak ayrıştırmaya çalışır. Sonuçta elde edilen nesneyi döndürür veya dize JSON olarak ayrıştırılamazsa TypeError değerini döndürür.
formData Gövdenin baytlarını multipart/form-data veya application/x-www-form-urlencoded olarak kodlanmış bir HTML formu olarak yorumlar. FormData nesnesini döndürür veya veriler ayrıştırılamazsa TypeError hatası verir.
body Gövde verileri için bir ReadableStream döndürür.

Örneğin:

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]

Önbellekten alma

Bir öğeyi önbellekte bulmak için match yöntemini kullanabilirsiniz.

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

request bir dize ise tarayıcı, new Request(request) işlevini çağırarak dizeyi Request olarak dönüştürür. İşlev, eşleşen bir giriş bulunursa Response, aksi halde undefined olarak çözümlenen bir Promise döndürür.

Tarayıcı, iki Requests değerinin eşleşip eşleşmediğini belirlemek için URL'den daha fazlasını kullanır. Farklı sorgu dizeleri, Vary üstbilgileri veya HTTP yöntemleri (GET, POST, PUT vb.) içeren iki istek farklı kabul edilir.

İkinci parametre olarak bir seçenekler nesnesi ileterek bunların bazılarını veya tümünü yoksayabilirsiniz.

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

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

Birden fazla önbelleğe alınan istek eşleşirse ilk oluşturulan istek döndürülür. Eşleşen tüm yanıtları almak istiyorsanız cache.matchAll() kullanabilirsiniz.

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

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

Kısayol olarak, her önbelleğe ait cache.match() işlevini çağırmak yerine caches.match() işlevini kullanarak tüm önbellekleri aynı anda arayabilirsiniz.

Aranıyor

Cache API, bir Response nesnesiyle eşleşen girişler dışında istekleri veya yanıtları aramak için bir yöntem sağlamaz. Ancak filtreleme kullanarak veya dizin oluşturarak kendi aramanızı uygulayabilirsiniz.

Filtreleme

Kendi aramanızı uygulamanın bir yolu, tüm girişleri iterasyonla gözden geçirmek ve istediğiniz girişleri filtrelemektir. URL'leri .png ile biten tüm öğeleri bulmak istediğinizi varsayalım.

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

Bu sayede, girişleri filtrelemek için Request ve Response nesnelerinin herhangi bir özelliğini kullanabilirsiniz. Büyük veri kümelerinde arama yaparsanız bu işlemin yavaş olacağını unutmayın.

Dizin oluşturma

Kendi aramanızı uygulamanın diğer yolu, aranabilir girişlerin ayrı bir dizini oluşturmak ve dizini IndexedDB'de depolamaktır. IndexedDB bu tür işlemler için tasarlandığından, çok sayıda girişle çok daha iyi performans gösterir.

Request URL'sini, aranabilir mülklerle birlikte depolarsanız aramayı yaptıktan sonra doğru önbelleğe alma girişini kolayca alabilirsiniz.

Öğe silme

Bir öğeyi önbellekten silmek için:

cache.delete(request);

Burada istek, Request veya URL dizesi olabilir. Bu yöntem ayrıca cache.match ile aynı seçenekler nesnesini alır. Böylece aynı URL için birden fazla Request/Response çiftini silebilirsiniz.

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

Önbelleği silme

Bir önbelleği silmek için caches.delete(name) numaralı telefonu arayın. Bu işlev, önbellek varsa ve silinmişse true ya da aksi halde false şeklinde çözümlenen bir Promise döndürür.

Teşekkürler

Bu makalenin ilk olarak WebFundamentals'ta yayınlanan orijinal sürümünü yazan Mat Scales'e teşekkür ederiz.