Uygulama verilerinizi çevrimdışı 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 normal istekler ve uygulamanızı çalıştırırken oluşturulan yanıtlar olabilir ya da yalnızca verileri daha sonra kullanmak üzere saklamak amacıyla oluşturulabilir.
Cache API, hizmet çalışanlarının ağ hızından veya kullanılabilirlikten bağımsız olarak hızlı yanıt verebilmek için ağ isteklerini önbelleğe almasını sağlamak amacıyla tasarlanmıştır. Ancak API, genel bir depolama mekanizması olarak da kullanılabilir.
Nerelerde kullanılabilir?
Cache API, tüm modern tarayıcılarda kullanılabilir. API, genel caches
özelliği aracılığıyla gösterilir. Böylece, basit bir özellik algılaması kullanarak API'nin varlığını test edebilirsiniz:
const cacheAvailable = 'caches' in self;
Önbellek API'sine bir pencereden, iframe'den, çalışandan veya hizmet çalışanından erişilebilir.
Neler depolanabilir?
Önbellekler yalnızca HTTP isteklerini ve yanıtlarını temsil eden Request
ve Response
nesne çiftlerini sırasıyla depolar. Ancak istekler ve yanıtlar, HTTP üzerinden aktarılabilecek her tür veriyi içerebilir.
Ne kadar depolanabilir?
Kısacası, çok fazla, en az birkaç yüz megabayt ve potansiyel olarak yüzlerce gigabayt veya daha fazla. Tarayıcı uygulamaları farklılık gösterir, ancak kullanılabilen depolama alanı genellikle cihazdaki kullanılabilir depolama alanına göre değişir.
Önbellek oluşturma ve açma
Bir önbelleği açmak için caches.open(name)
yöntemini kullanarak önbelleğin adını tek parametre olarak geçirin. Adlandırılmış önbellek yoksa oluşturulur. Bu yöntem, Cache
nesnesiyle çözümlenen bir Promise
döndürür.
const cache = await caches.open('my-cache');
// do something with cache...
Önbelleğe ekleme
Bir öğeyi önbelleğe eklemenin üç yolu vardır: add
, addAll
ve put
.
Üç yöntem de bir Promise
döndürür.
cache.add
İlki cache.add()
. Request
veya URL (string
) olmak üzere tek bir parametre 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 kaynaklar arası isteklerin, 0
tutarında 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
Sonra cache.addAll()
var. add()
işlevine benzer şekilde çalışır ancak Request
nesne veya URL'den (string
) oluşan bir dizi kullanır. Bu, her bir istek için cache.add
çağrısına benzer şekilde işler. Tek fark, tek bir istek önbelleğe alınmazsa Promise
bunu 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 özellik, retrieving ile ilgili bölümde açıklanan eşleştirme kurallarını kullanır.
cache.put
Son olarak, ağdan bir yanıtı depolamanıza veya kendi Response
öğenizi oluşturup depolamanıza olanak tanıyan cache.put()
vardır. İki parametre gerekir. Birincisi 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öntemlerinden daha geniş kapsamlıdır 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.
İstek nesneleri oluşturma
Depolanan öğe için bir URL kullanarak Request
nesnesini oluşturun:
const request = new Request('/my-data-store/item-id');
Yanıt nesneleriyle çalışma
Response
nesne oluşturucusu; Blob
, ArrayBuffer
, FormData
nesneleri ve dizeler de dahil olmak üzere 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 gövdesine erişmek istiyorsanız kullanabileceğiniz birkaç yardımcı yöntem vardır. Her biri, farklı türde bir değerle çözümlenen bir Promise
döndürür.
Yöntem | Açıklama |
---|---|
arrayBuffer |
Baytlara serileştirilmiş olarak, gövdesi içeren bir ArrayBuffer döndürür.
|
blob |
Bir Blob döndürür. Response bir Blob ile oluşturulmuşsa bu yeni Blob aynı türe sahip olur. Aksi takdirde Response öğesinin Content-Type özelliği kullanılır.
|
text |
Gövdenin baytlarını UTF-8 olarak kodlanmış bir dize olarak yorumlar. |
json |
Gövdenin baytlarını UTF-8 olarak kodlanmış dize olarak yorumlar, ardından bunu JSON olarak ayrıştırmaya çalışır. Sonuç nesnesini döndürür veya dize JSON olarak ayrıştırılamazsa bir TypeError 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. Bir FormData nesnesi döndürür veya veriler ayrıştırılamazsa bir TypeError döndürür.
|
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
Önbellekteki bir öğeyi bulmak için match
yöntemini kullanabilirsiniz.
const response = await cache.match(request);
console.log(request, response);
request
bir dizeyse tarayıcı new Request(request)
yöntemini çağırarak bunu Request
biçimine dönüştürür. İşlev, eşleşen bir giriş bulunursa Response
olarak çözümlenen bir Promise
, aksi halde undefined
döndürür.
İki Requests
öğesinin eşleşip eşleşmediğini belirlemek için tarayıcı sadece URL'den daha fazlasını kullanır. Farklı sorgu dizeleri, Vary
başlıkları veya HTTP yöntemleri (GET
, POST
, PUT
vb.) olan iki istek farklı olarak kabul edilir.
Bir seçenek nesnesini ikinci parametre olarak geçirerek bunların bazılarını veya tümünü yok sayabilirsiniz.
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 önbellek için cache.match()
çağrısı yapmak yerine caches.match()
kullanarak tüm önbelleklerde aynı anda arama yapabilirsiniz.
Aranıyor
Cache API, bir Response
nesnesiyle eşleşen girişler dışında istek veya yanıt aramak için bir yol sağlamaz. Ancak, filtreleme veya bir dizin oluşturarak kendi aramanızı uygulayabilirsiniz.
Filtreleme
Kendi aramanızı uygulamanın bir yolu, tüm girişleri yinelemek ve istediklerinize göre 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 şekilde, girişleri filtrelemek için Request
ve Response
nesnelerinin herhangi bir özelliğini kullanabilirsiniz. Büyük veri kümelerinde arama yapıyorsanız bu işlemin yavaş olduğunu unutmayın.
Dizin oluşturma
Kendi aramanızı uygulamanın diğer bir yolu, aranabilecek ayrı bir giriş dizini oluşturmak ve dizini IndexedDB'de saklamaktır. IndexedDB'nin bunun için tasarladığı işlem türü bu olduğundan, çok sayıda girişle çok daha iyi performans gösteriyor.
Request
öğesinin URL'sini aranabilir özelliklerin yanında saklıyorsanız, aramayı yaptıktan sonra doğru önbellek girişini kolayca alabilirsiniz.
Öğe silme
Bir öğeyi önbellekten silmek için:
cache.delete(request);
Burada istek bir Request
veya URL dizesi olabilir. Bu yöntem, cache.match
ile aynı seçenekler nesnesini de alır ve böylece, aynı URL için birden fazla Request
/Response
çiftini silmenize olanak tanır.
cache.delete('/example/file.txt', {ignoreVary: true, ignoreSearch: true});
Önbellek silme
Bir önbelleği silmek için caches.delete(name)
çağrısı yapın. Bu işlev, önbellek varsa ve silindiyse true
, aksi halde false
olarak çözümlenen bir Promise
döndürür.
Teşekkür ederiz
Bu makalenin orijinal versiyonunu yazan ve ilk kez WebFundamentals'ta yayınlanan Mat Scales'e teşekkür ederiz.