تعرَّف على كيفية استخدام Cache API لإتاحة بيانات تطبيقك بلا اتصال بالإنترنت.
cache API هي نظام لتخزين بيانات الشبكة واستردادها. والردود عليها. قد تكون هذه طلبات عادية والردود التي تم إنشاؤها أثناء تشغيل التطبيق، أو يمكنهم سيتم إنشاؤها فقط لغرض تخزين البيانات لاستخدامها في وقت لاحق.
تم إنشاء Cache API لتمكين موظفي الخدمة من تخزين طلبات الشبكة في ذاكرة التخزين المؤقت. بحيث يمكنهم تقديم استجابات سريعة، بغض النظر عن سرعة الشبكة أو مدى التوفر. ومع ذلك، يمكن أيضًا استخدام واجهة برمجة التطبيقات كآلية تخزين عامة.
أماكن توفّر المنصة
وتتوفر واجهة Cache API في جميع المتصفحات الحديثة. من المهم
باستخدام السمة caches
العالمية، حتى تتمكّن من إجراء اختبار لمعرفة ما إذا كان
واجهة برمجة التطبيقات من خلال اكتشاف ميزات بسيطة:
const cacheAvailable = 'caches' in self;
يمكن الوصول إلى Cache API من نافذة أو iframe أو عامل أو مشغِّل خدمات.
المعلومات التي يمكن تخزينها
تُخزِّن عمليات التخزين المؤقت فقط أزواج Request
و
كائنات Response
التي تمثل طلبات واستجابات HTTP،
على التوالي. ومع ذلك، يمكن أن تحتوي الطلبات والردود على أي نوع من البيانات
التي يمكن نقلها عبر HTTP.
ما مقدار البيانات التي يمكن تخزينها؟
باختصار، كثيرًا أو مئات الميغابايت على الأقل، ومن المحتمل مئات الجيجابايت أو أكثر. تختلف عمليات تنفيذ المتصفح، ولكن حجم البيانات من مساحة التخزين المتوفرة تستند عادةً إلى حجم مساحة التخزين المتاحة الجهاز.
إنشاء ذاكرة تخزين مؤقت وفتحها
لفتح ذاكرة تخزين مؤقت، استخدِم الطريقة 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
.
أو عنوان URL (string
). يرسل طلبًا إلى الشبكة ويخزن الاستجابة
في ذاكرة التخزين المؤقت. إذا كانت
أو فشل الاسترجاع أو إذا لم يكن رمز حالة الاستجابة ضمن النطاق 200،
فلن يتم تخزين أي شيء وسيتم رفض Promise
. يُرجى العِلم أنّ الوصول إلى البيانات من مصادر متعددة
لا يمكن تخزين الطلبات التي ليست في وضع CORS لأنها تعرض status
من
0
لا يمكن تخزين هذه الطلبات إلا مع 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
من العناصر أو عناوين URL (string
s). هذا يعمل بشكل مشابه
الاتصال بالرقم cache.add
لكل طلب فردي، باستثناء Promise
يرفض إذا لم يتم التخزين المؤقت لأي طلب فردي.
const urls = ['/weather/today.json', '/weather/tomorrow.json'];
cache.addAll(urls);
وفي كل حالة من هذه الحالات، يحلّ إدخال جديد محلّ أي إدخال حالي مطابق. ويستخدِم هذا القواعد المطابقة نفسها الموضّحة في القسم المتعلّق .
cache.put
وأخيرًا، هناك cache.put()
، الذي يتيح لك تخزين أي رد
من الشبكة، أو إنشاء Response
الخاص بك وتخزينه. يستغرق الأمر
المعلَمات. يمكن أن يكون العنصر الأول كائن Request
أو عنوان URL (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()
،
بتخزين ردود غير تابعة لسياسة مشاركة الموارد المتعددة المصادر (CORS)، أو استجابات أخرى عندما تكون الحالة
رمز الاستجابة ليس ضمن نطاق 200. سيتم استبدال أي بيانات
الردود على نفس الطلب.
إنشاء عناصر "الطلبات"
يمكنك إنشاء الكائن Request
باستخدام عنوان URL للعنصر الذي يتم تخزينه:
const request = new Request('/my-data-store/item-id');
التعامل مع عناصر الاستجابة
تقبل الدالة الإنشائية للكائن Response
أنواعًا عديدة من البيانات، بما في ذلك
عناصر Blob
وArrayBuffer
وFormData
وسلاسل
const imageBlob = new Blob([data], {type: 'image/jpeg'});
const imageResponse = new Response(imageBlob);
const stringResponse = new Response('Hello world');
يمكنك ضبط نوع MIME لـ Response
من خلال ضبط العنوان المناسب.
const options = {
headers: {
'Content-Type': 'application/json'
}
}
const jsonResponse = new Response('{}', options);
إذا استعدت Response
وأردت الوصول إلى نصه، هناك
والعديد من طرق المساعدة التي يمكنك استخدامها. تقوم كل منها بإرجاع Promise
يتم حلها
بقيمة من نوع مختلف.
الطريقة | الوصف |
---|---|
arrayBuffer |
عرض ArrayBuffer يتضمن النص الأساسي المتسلسل إلى
بايت.
|
blob |
تعرض Blob . إذا تم إنشاء Response
باستخدام Blob ، سيحصل Blob الجديد على
الكتابة. وبخلاف ذلك، يتم استخدام Content-Type
يتم استخدام Response .
|
text |
يفسّر وحدات بايت النص كسلسلة مرمّزة بترميز UTF-8. |
json |
يفسّر وحدات بايت النص كسلسلة مشفّرة بترميز UTF-8، ثم يحاول
لتحليله كملف JSON. لعرض الكائن الناتج، أو طرح
TypeError إذا تعذّر تحليل السلسلة كملف JSON.
|
formData |
تفسّر وحدات بايت النص الأساسي كنموذج HTML، مرمّزًا إما
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
سلسلة، يحوّلها المتصفّح إلى Request
من خلال استدعاء
new Request(request)
ترجع الدالة قيمة Promise
التي يتم حلها إلى
أو Response
في حال العثور على إدخال مطابق، أو undefined
بخلاف ذلك.
لتحديد ما إذا كان حقلا Requests
متطابقَين، يستخدم المتصفّح أكثر من عنوان URL فقط. قطعتان
تُعتبر الطلبات مختلفة إذا كانت تحتوي على سلاسل طلبات بحث مختلفة،
Vary
أو طرق HTTP (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.`);
كاختصار، يمكنك البحث في جميع ذاكرات التخزين المؤقت في وقت واحد باستخدام caches.match()
بدلاً من طلب الرقم cache.match()
لكل ذاكرة تخزين مؤقت.
جارٍ البحث
لا توفّر Cache API طريقة للبحث عن الطلبات أو الردود
باستثناء الإدخالات المتطابقة مع عنصر Response
. ومع ذلك، يمكنك
تنفيذ البحث الخاص بك باستخدام التصفية أو عن طريق إنشاء فهرس.
الفلترة
تتمثل إحدى طرق تنفيذ بحثك في التكرار على جميع الإدخالات
قم بالتصفية وصولاً إلى تلك التي تريدها. لنفترض أنك تريد العثور على جميع
من العناصر التي تحتوي على عناوين URL تنتهي بـ .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 من أجلها تقدم أداءً أفضل بكثير باستخدام أعداد كبيرة من الإدخالات.
في حال تخزين عنوان URL للسمة Request
إلى جانب المواقع الإلكترونية القابلة للبحث
يمكنك بسهولة استرداد الإدخال الصحيح لذاكرة التخزين المؤقت بعد إجراء البحث.
حذف عنصر
لحذف عنصر من ذاكرة تخزين مؤقت:
cache.delete(request);
حيث يمكن أن يكون الطلب Request
أو سلسلة عنوان URL. تستخدم هذه الطريقة أيضًا
نفس كائن الخيارات مثل cache.match
، ما يسمح لك بحذف عدة عناصر
زوجان من Request
/Response
لعنوان URL نفسه
cache.delete('/example/file.txt', {ignoreVary: true, ignoreSearch: true});
حذف ذاكرة تخزين مؤقت
لحذف ذاكرة تخزين مؤقت، اتصِل بالرقم caches.delete(name)
. تُرجع هذه الدالة دالة
Promise
الذي يتم تغييره إلى true
في حال توفّر ذاكرة التخزين المؤقت وحذفها
false
بخلاف ذلك.
شكرًا
وبفضل مات Scales الذي كتب النسخة الأصلية من هذه المقالة، لأول مرة على WebFundamentals.