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ı depolayan ve alan bir sistemdir. Bunlar, uygulamanızın çalışması sırasında oluşturulan normal istekler ve yanıtlar olabilir veya 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;
Cache API'ye bir pencereden, iFrame'den, çalışandan veya hizmet çalışanından erişilebilir.
Hangi veriler saklanabilir?
Önbellekler yalnızca sırasıyla HTTP isteklerini ve yanıtlarını temsil eden Request
ve Response
nesne çiftlerini depolar. Ancak istekler ve yanıtlar, HTTP üzerinden aktarılabilen her türlü veriyi içerebilir.
Ne kadar veri depolanabilir?
Özetle, çok. En az birkaç yüz megabayt, hatta yüzlerce gigabayt veya daha fazlası. 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 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 ekleme
Önbelleğe öğe eklemenin üç yolu vardır: add
, addAll
ve put
.
Üç yöntem de bir Promise
döndürür.
cache.add
İlk olarak cache.add()
'ten bahsedelim. Bir Request
veya URL (string
) parametresi alır. Ağa istek gönderir ve yanıtı önbellekte depolar. Getirme işlemi 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 saklanabilir.
// 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 girişin üzerine eşleşen mevcut girişin 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()
'den daha fazla izin verir ve CORS olmayan yanıtları ya da 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');
Response nesneleriyle çalışma
Response
nesne kurucusu; Blob
, ArrayBuffer
, FormData
nesneleri ve dizeler 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 üstbilgeyi ayarlayarak Response
öğesinin MIME türünü belirleyebilirsiniz.
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 ile kodlanmış bir dize olarak yorumlar, ardından JSON olarak ayrıştırmayı dener. 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. Bir FormData nesnesi döndürür veya veriler ayrıştırılamazsa TypeError atar.
|
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
değerine, aksi takdirde undefined
değerine çö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ınmış istek eşleşirse önce 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, Response
nesnesi ile 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, cache.match
ile aynı seçenek nesnesini de alır. Bu sayede aynı URL için birden fazla Request
/Response
çiftini silebilirsiniz.
cache.delete('/example/file.txt', {ignoreVary: true, ignoreSearch: true});
Önbelleği silme
Önbelleği silmek için caches.delete(name)
'ü arayın. Bu işlev, önbellek mevcutsa ve silindiyse true
olarak çözümlenen bir Promise
veya aksi takdirde false
döndürür.
Teşekkürler
İlk olarak WebFundamentals'da yayınlanan bu makalenin orijinal sürümünü yazan Mat Scales'e teşekkür ederiz.