अपने ऐप्लिकेशन डेटा को ऑफ़लाइन उपलब्ध कराने के लिए, कैश एपीआई इस्तेमाल करने का तरीका जानें.
कैश एपीआई सिस्टम, नेटवर्क अनुरोधों और उनसे जुड़ी प्रतिक्रियाओं को सेव करने और वापस पाने का काम करता है. ये सामान्य अनुरोध और जवाब हो सकते हैं जो आपका ऐप्लिकेशन चलाने के दौरान बनाए जाते हैं या इन्हें सिर्फ़ बाद में इस्तेमाल करने के लिए डेटा सेव करने के मकसद से बनाया जा सकता है.
कैश एपीआई को इसलिए बनाया गया था, ताकि सर्विस वर्कर नेटवर्क के अनुरोधों को कैश मेमोरी में सेव कर सकें. इससे वे तेज़ी से रिस्पॉन्स दे पाएंगे, चाहे नेटवर्क की स्पीड कुछ भी हो या नेटवर्क की उपलब्धता जैसी भी हो. हालांकि, इस एपीआई का इस्तेमाल सामान्य स्टोरेज तरीके के तौर पर भी किया जा सकता है.
YouTube TV कहां उपलब्ध है?
कैश एपीआई सभी आधुनिक ब्राउज़र में उपलब्ध है. इसे ग्लोबल caches
प्रॉपर्टी के ज़रिए दिखाया जाता है, ताकि आप आसान सुविधा की मदद से एपीआई की मौजूदगी की जांच कर सकें:
const cacheAvailable = 'caches' in self;
कैश एपीआई को किसी विंडो, iframe, वर्कर या सर्विस वर्कर से ऐक्सेस किया जा सकता है.
क्या सेव किया जा सकता है
कैश मेमोरी में, Request
और Response
ऑब्जेक्ट के सिर्फ़ जोड़े स्टोर होते हैं, जो एचटीटीपी अनुरोध और रिस्पॉन्स दिखाते हैं. हालांकि, अनुरोधों और जवाबों में ऐसा कोई भी डेटा शामिल
हो सकता है जिसे एचटीटीपी पर ट्रांसफ़र किया जा सके.
कितना डेटा सेव किया जा सकता है?
संक्षेप में, बहुत ज़्यादा, कम से कम कुछ सौ मेगाबाइट और संभावित रूप से सैकड़ों गीगाबाइट या उससे ज़्यादा. ब्राउज़र को लागू करने के तरीके अलग-अलग होते हैं, लेकिन डिवाइस पर कितना स्टोरेज उपलब्ध है, यह आम तौर पर डिवाइस पर उपलब्ध स्टोरेज पर निर्भर करता है.
कैश मेमोरी बनाना और खोलना
कैश मेमोरी खोलने के लिए, caches.open(name)
तरीके का इस्तेमाल करें. साथ ही, कैश मेमोरी को एक पैरामीटर के तौर पर पास करें. अगर नाम वाली कैश मेमोरी मौजूद नहीं है, तो इसे
बना दिया जाता है. यह तरीका ऐसा Promise
दिखाता है जो Cache
ऑब्जेक्ट से रिज़ॉल्व हो जाता है.
const cache = await caches.open('my-cache');
// do something with cache...
कैश मेमोरी में जोड़ा जा रहा है
किसी आइटम को कैश मेमोरी में जोड़ने के तीन तरीके हैं - add
, addAll
, और put
.
तीनों तरीकों से Promise
दिखता है.
cache.add
सबसे पहले, cache.add()
है. इसमें एक पैरामीटर होता है, चाहे Request
या यूआरएल (string
). यह नेटवर्क से अनुरोध करता है और रिस्पॉन्स को कैश मेमोरी में सेव करता है. अगर
फ़ेच नहीं किया जा सका या जवाब का स्टेटस कोड 200 की रेंज में नहीं है,
तो कुछ भी सेव नहीं किया जाता और Promise
अस्वीकार कर देता है. ध्यान दें कि ऐसे क्रॉस-ऑरिजिन अनुरोध सेव नहीं किए जा सकते जो सीओआरएस मोड में नहीं हैं, क्योंकि वे 0
का status
दिखाते हैं. ऐसे अनुरोध सिर्फ़ 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
आगे है, cache.addAll()
. यह add()
की तरह ही काम करता है, लेकिन इसमें Request
ऑब्जेक्ट या यूआरएल (string
) की एक शृंखला होती है. यह हर अनुरोध के लिए, cache.add
को कॉल करने की तरह ही काम करता है. हालांकि, अगर किसी एक अनुरोध को कैश मेमोरी में सेव नहीं किया जाता, तो Promise
उसे अस्वीकार कर देता है.
const urls = ['/weather/today.json', '/weather/tomorrow.json'];
cache.addAll(urls);
इनमें से हर मामले में, मौजूदा एंट्री की जगह नई एंट्री डालें. इसमें, मैच करने वाले उन ही नियमों का इस्तेमाल होता है जिनके बारे में retrieving के सेक्शन में बताया गया है.
cache.put
आखिर में, cache.put()
है. इसकी मदद से, नेटवर्क से मिले जवाब को सेव किया जा सकता है
या खुद का Response
बनाया और सेव किया जा सकता है. इसके लिए दो पैरामीटर
की ज़रूरत होती है. पहला विकल्प, Request
ऑब्जेक्ट या यूआरएल (string
) हो सकता है.
दूसरा विकल्प Response
होना चाहिए, जिसे नेटवर्क से या आपके कोड से जनरेट किया गया हो.
// 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()
वाला तरीका, add()
या addAll()
की तुलना में ज़्यादा अनुमति देता है. साथ ही, इससे बिना सीओआरएस या ऐसे दूसरे जवाबों को सेव किया जा सकता है जिनमें रिस्पॉन्स का स्टेटस कोड 200 की रेंज में न हो. यह उसी अनुरोध के सभी पिछले
जवाबों को ओवरराइट कर देगा.
अनुरोध ऑब्जेक्ट बनाना
सेव की जा रही चीज़ के लिए, यूआरएल का इस्तेमाल करके Request
ऑब्जेक्ट बनाएं:
const request = new Request('/my-data-store/item-id');
Response ऑब्जेक्ट के साथ काम करना
Response
ऑब्जेक्ट कंस्ट्रक्टर कई तरह का डेटा स्वीकार करता है. इनमें Blob
, ArrayBuffer
, FormData
ऑब्जेक्ट, और स्ट्रिंग शामिल हैं.
const imageBlob = new Blob([data], {type: 'image/jpeg'});
const imageResponse = new Response(imageBlob);
const stringResponse = new Response('Hello world');
सही हेडर सेट करके, Response
का MIME टाइप सेट किया जा सकता है.
const options = {
headers: {
'Content-Type': 'application/json'
}
}
const jsonResponse = new Response('{}', options);
अगर आपको Response
मिल गया है और आपको इसके मुख्य हिस्से को ऐक्सेस करना है, तो ऐसे कई हेल्पर तरीके हैं जिनका इस्तेमाल किया जा सकता है. हर फ़ंक्शन एक Promise
देता है, जो अलग-अलग टाइप की वैल्यू के साथ रिज़ॉल्व होता है.
तरीका | जानकारी |
---|---|
arrayBuffer |
यह फ़ंक्शन, मुख्य भाग वाला ArrayBuffer दिखाता है. इसे बाइट के हिसाब से क्रम में लगाया जाता है.
|
blob |
Blob देता है. अगर Response को Blob की मदद से बनाया गया था, तो इस नए Blob का टाइप भी एक ही है. ऐसा नहीं होने पर, Response के Content-Type का इस्तेमाल किया जाता है.
|
text |
यह बॉडी के बाइट को UTF-8 कोड में बदली गई स्ट्रिंग के तौर पर समझता है. |
json |
यह बॉडी के बाइट को UTF-8 कोड में बदली गई स्ट्रिंग के तौर पर समझता है, फिर उसे
JSON के तौर पर पार्स करने की कोशिश करता है. नतीजे के तौर पर मिलने वाला ऑब्जेक्ट लौटाता है या अगर स्ट्रिंग को JSON के रूप में पार्स नहीं किया जा सकता, तो TypeError थ्योरी करता है.
|
formData |
बॉडी के बाइट को एचटीएमएल फ़ॉर्म के तौर पर इंटरप्रेट करता है, जिन्हें
multipart/form-data या
application/x-www-form-urlencoded के तौर पर एन्कोड किया जाता है. यह FormData
ऑब्जेक्ट देता है या डेटा पार्स न हो पाने पर, TypeError दिखाता है.
|
body |
शरीर के डेटा के लिए ReadableStream दिखाता है. |
उदाहरण के लिए
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]
कैश से लिया जा रहा है
कैश मेमोरी में मौजूद किसी आइटम को ढूंढने के लिए, match
तरीके का इस्तेमाल किया जा सकता है.
const response = await cache.match(request);
console.log(request, response);
अगर request
एक स्ट्रिंग है, तो ब्राउज़र new Request(request)
को कॉल करके उसे Request
में बदल देता है. फ़ंक्शन, एक Promise
दिखाता है, जो मिलता-जुलता एंट्री मिलने पर Response
दिखाता है. अगर ऐसा नहीं है, तो undefined
दिखाता है.
यह पता लगाने के लिए कि दो Requests
मेल खाते हैं या नहीं, ब्राउज़र सिर्फ़ यूआरएल के अलावा दूसरी चीज़ों का भी इस्तेमाल करता है. दो अनुरोधों को अलग-अलग तब माना जाता है, जब उनकी क्वेरी स्ट्रिंग, Vary
हेडर या एचटीटीपी के तरीके (GET
, POST
, PUT
वगैरह) अलग-अलग हों.
एक विकल्प ऑब्जेक्ट को दूसरे पैरामीटर के तौर पर पास करके, इनमें से कुछ या सभी चीज़ों को अनदेखा किया जा सकता है.
const options = {
ignoreSearch: true,
ignoreMethod: true,
ignoreVary: true
};
const response = await cache.match(request, options);
// do something with the response
अगर कैश मेमोरी में सेव किए गए एक से ज़्यादा अनुरोध मेल खाते हैं, तो पहले बनाए गए अनुरोध को वापस
दिया जाता है. अगर आपको मिलते-जुलते सभी जवाब फिर से पाने हैं, तो
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.`);
शॉर्टकट के तौर पर, हर कैश मेमोरी के लिए cache.match()
को कॉल करने के बजाय caches.match()
का इस्तेमाल करके, एक साथ सभी कैश मेमोरी में खोजा जा सकता है.
खोजा जा रहा है
कैश एपीआई, किसी Response
ऑब्जेक्ट से एंट्री का मिलान करने के अलावा, अनुरोधों या जवाबों को खोजने का कोई तरीका नहीं देता. हालांकि, फ़िल्टर का इस्तेमाल करके या इंडेक्स बनाकर, अपनी खोज को लागू किया जा सकता है.
फ़िल्टर करना
अपनी खोज लागू करने का एक तरीका यह है कि सभी एंट्री को दोहराएं और
अपनी पसंद के हिसाब से फ़िल्टर करें. मान लें कि आपको उन सभी आइटम को खोजना है
जिनके यूआरएल के आखिरी शब्द .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;
}
इस तरह, एंट्री को फ़िल्टर करने के लिए, Request
और Response
ऑब्जेक्ट की किसी भी प्रॉपर्टी का इस्तेमाल किया जा सकता है. ध्यान दें कि अगर डेटा के बड़े सेट में खोज की जाती है, तो यह प्रोसेस धीमी हो जाती है.
इंडेक्स बनाना
अपनी खोज लागू करने का एक और तरीका यह है कि आप एंट्री का एक अलग इंडेक्स बनाए रखें, जिसे खोजा जा सके और इंडेक्स को IndexedDB में सेव किया जा सके. ऐसा इसलिए है, क्योंकि IndexedDB को इस तरह डिज़ाइन किया गया है कि यह बड़ी संख्या में एंट्री के साथ, बेहतर परफ़ॉर्मेंस देता है.
अगर Request
का यूआरएल, खोजने लायक प्रॉपर्टी के साथ सेव किया जाता है, तो
खोजने के बाद आपको आसानी से सही कैश एंट्री मिल सकती है.
कोई आइटम मिटाना
कैश मेमोरी से कोई आइटम मिटाने के लिए:
cache.delete(request);
जहां अनुरोध, Request
या यूआरएल स्ट्रिंग हो सकता है. इस तरीके में, वही विकल्प ऑब्जेक्ट मिलते हैं जो cache.match
को मिलते हैं. इससे एक ही यूआरएल के लिए, कई Request
/Response
जोड़े मिटाए जा सकते हैं.
cache.delete('/example/file.txt', {ignoreVary: true, ignoreSearch: true});
कैश मेमोरी मिटाना
कैश मेमोरी मिटाने के लिए, caches.delete(name)
पर कॉल करें. अगर कैश मेमोरी मौजूद है और उसे मिटा दिया गया है, तो यह फ़ंक्शन true
का Promise
दिखाता है. अगर ऐसा नहीं है, तो false
दिखाता है.
धन्यवाद
इस लेख का मूल वर्शन लिखने वाले मैट स्केल्स को धन्यवाद. यह लेख पहली बार WebFundamentals पर दिखाया गया था.