فهرسة الصفحات التي يمكن الوصول إليها بلا اتصال بالإنترنت باستخدام Content Indexing API

تفعيل مهام الخدمة لإعلام المتصفّحات بالصفحات التي تعمل بلا إنترنت

ما هي Content Indexing API؟

يتيح لك استخدام تطبيق ويب تقدّمي الوصول إلى المعلومات التي تهمّ المستخدمين، مثل الصور والفيديوهات والمقالات وغير ذلك، بغض النظر عن الحالة الحالية لاتصالك بالشبكة. تقدّم لك تكنولوجيات مثل خدمة workers وCache Storage API وIndexedDB العناصر الأساسية لتخزين البيانات وعرضها عندما يتفاعل المستخدمون مباشرةً مع تطبيق متوافق مع تقنية PWA. ولكن إنشاء تطبيق متوافق مع الأجهزة الجوّالة يعمل بلا إنترنت بجودة عالية هو جزء فقط من القصة. إذا لم يدرك المستخدمون أنّ محتوى تطبيق الويب متاح في حال عدم توفّر اتصال بالإنترنت، لن يستفيدوا إلى أقصى حد من الجهد الذي بذلته لتنفيذ هذه الوظيفة.

هذه مشكلة اكتشاف. كيف يمكن لتطبيقك المتوافق مع الأجهزة الجوّالة (PWA) إطلاع المستخدمين على المحتوى المتاح بلا إنترنت حتى يتمكّنوا من اكتشافه وعرضه؟ واجهة برمجة التطبيقات Content Indexing API هي حلّ لهذه المشكلة. إنّ الجزء المخصّص للمطوّرين من هذا الحل هو إضافة إلى مهام الخدمة، ما يسمح للمطوّرين بإضافة عناوين URL والبيانات الوصفية للصفحات المتوافقة مع وضع عدم الاتّصال بالإنترنت إلى فهرس محلي يديره المتصفّح. يتوفّر هذا التحسين في الإصدار 84 من Chrome والإصدارات الأحدث.

بعد تعبئة الفهرس بمحتوى من تطبيقك المتوافق مع الأجهزة الجوّالة (PWA) وأي تطبيقات مماثلة مثبّتة، سيعرض المتصفّح المحتوى كما هو موضّح أدناه.

لقطة شاشة لعنصر قائمة "عمليات التنزيل" في صفحة علامة التبويب الجديدة في Chrome
أولاً، اختَر عمليات التنزيل من قائمة صفحة علامة التبويب الجديدة في Chrome.
الوسائط والمقالات التي تمت إضافتها إلى الفهرس
ستظهر الوسائط والمقالات التي تمت إضافتها إلى الفهرس في مقالات مقترَحة لك.

بالإضافة إلى ذلك، يمكن لمتصفّح Chrome اقتراح المحتوى بشكل استباقي عندما يرصد أنّ أحد المستخدِمين غير متصل بالإنترنت.

لا تشكّل Content Indexing API طريقة بديلة لتخزين المحتوى في ذاكرة التخزين المؤقت. وهي طريقة لتقديم بيانات وصفية عن الصفحات التي سبق أن تم تخزينها مؤقتًا في ذاكرة التخزين المؤقت من قِبل معالج الخدمة، حتى يتمكّن المتصفّح من عرض هذه الصفحات عندما يُحتمل أن يريد المستخدمون مشاهدتها. تساعد Content Indexing API في اكتشاف الصفحات المخزّنة مؤقتًا.

أمثلة واقعية

إنّ أفضل طريقة للتعرّف على Content Indexing API هي تجربة نموذج تطبيق.

  1. تأكَّد من استخدام متصفّح ومنصّة متوافقَين. في الوقت الحالي، يقتصر ذلك على الإصدار 84 من Chrome أو الإصدارات الأحدث على Android. انتقِل إلى about://version للاطّلاع على إصدار Chrome الذي تستخدمه.
  2. انتقِل إلى https://contentindex.dev.
  3. انقر على الزر + بجانب عنصر واحد أو أكثر من العناصر في القائمة.
  4. (اختياري) أوقِف اتصال جهازك بشبكة Wi-Fi وبيانات شبكة الجوّال، أو فعِّل وضع الطيران لمحاكاة إيقاف اتصال المتصفّح بالإنترنت.
  5. اختَر عمليات التنزيل من قائمة Chrome، وانتقِل إلى علامة التبويب مقالات مقترَحة لك.
  6. تصفَّح المحتوى الذي سبق لك حفظه.

يمكنك الاطّلاع على مصدر نموذج التطبيق على GitHub.

يوضّح نموذج تطبيق آخر، وهو تطبيق ويب متقدّم (PWA) لتطبيق "مذكرات"، استخدام Content Indexing API مع Web Share Target API. يوضّح الرمز البرمجي أسلوبًا للحفاظ على مزامنة Content Indexing API مع العناصر التي يخزنها تطبيق ويب باستخدام Cache Storage API.

استخدام واجهة برمجة التطبيقات

لاستخدام واجهة برمجة التطبيقات، يجب أن يتضمّن تطبيقك عامل خدمة وعناوين URL يمكن التنقّل فيها بلا إنترنت. إذا لم يكن تطبيق الويب يتضمّن حاليًا عامل خدمة، يمكن أن تبسِّط مكتبات Workbox عملية إنشاء عامل خدمة.

ما هو نوع عناوين URL التي يمكن فهرستها على أنّها متاحة بلا إنترنت؟

تتيح واجهة برمجة التطبيقات فهرسة عناوين URL التي تتوافق مع مستندات HTML. على سبيل المثال، لا يمكن فهرسة عنوان URL لملف وسائط في ذاكرة التخزين المؤقت مباشرةً. بدلاً من ذلك، عليك تقديم عنوان URL لصفحة تعرض الوسائط وتعمل بلا إنترنت.

من الأنماط المقترَحة إنشاء صفحة HTML "عارض" يمكنها قبول عنوان URL للوسائط الأساسية كمَعلمة طلب بحث، ثم عرض محتوياتملف، مع احتمال إضافة عناصر تحكّم أو محتوى إضافي على الصفحة.

لا يمكن لتطبيقات الويب إضافة عناوين URL إلى فهرس المحتوى إلا إذا كانت ضمن نطاق عامل الخدمة الحالي. بعبارة أخرى، لا يمكن لتطبيق الويب إضافة عنوان URL ينتمي إلى نطاق مختلف تمامًا إلى فهرس المحتوى.

نظرة عامة

تتيح Content Indexing API ثلاث عمليات: إضافة البيانات الوصفية وإدراجها وإزالتها. يتم عرض هذه الطرق من موقع إلكتروني جديد، وهو index، تمت إضافته إلى واجهة ServiceWorkerRegistration.

الخطوة الأولى في فهرسة المحتوى هي الحصول على مرجع إلى ServiceWorkerRegistration الحالي. استخدام navigator.serviceWorker.ready هو الطريقة الأكثر وضوحًا:

const registration = await navigator.serviceWorker.ready;

// Remember to feature-detect before using the API:
if ('index' in registration) {
  // Your Content Indexing API code goes here!
}

إذا كنت تُجري طلبات إلى Content Indexing API من داخل عامل خدمة، بدلاً من داخل صفحة ويب، يمكنك الرجوع إلى ServiceWorkerRegistration مباشرةً من خلال registration. سيكون محدّدًا مسبقًا كجزء من ServiceWorkerGlobalScope..

الإضافة إلى الفهرس

استخدِم طريقة add() لفهرسة عناوين URL والبيانات الوصفية المرتبطة بها. يمكنك تحديد متى تتم إضافة العناصر إلى الفهرس. قد تحتاج إلى إضافة محتوى إلى الفهرس استجابةً لإدخال، مثل النقر على زر "حفظ بلا إنترنت". أو يمكنك إضافة عناصر تلقائيًا في كل مرة يتم فيها تعديل البيانات المخزّنة مؤقتًا من خلال آلية مثل المزامنة الدورية في الخلفية.

await registration.index.add({
  // Required; set to something unique within your web app.
  id: 'article-123',

  // Required; url needs to be an offline-capable HTML page.
  url: '/articles/123',

  // Required; used in user-visible lists of content.
  title: 'Article title',

  // Required; used in user-visible lists of content.
  description: 'Amazing article about things!',

  // Required; used in user-visible lists of content.
  icons: [{
    src: '/img/article-123.png',
    sizes: '64x64',
    type: 'image/png',
  }],

  // Optional; valid categories are currently:
  // 'homepage', 'article', 'video', 'audio', or '' (default).
  category: 'article',
});

لا تؤثّر إضافة إدخال إلّا في فهرس المحتوى، ولا تضيف أيّ شيء إلى الذاكرة المؤقتة.

حالة خاصة: استدعاء add() من سياق window إذا كانت الرموز تعتمد على معالِج fetch

عند استدعاء add()، سيطلب Chrome عنوان URL لكل رمز لضمان توفّر نسخة من الرمز لاستخدامها عند عرض قائمة بالمحتوى المفهرَس.

  • إذا ناديت add() من سياق window (بمعنى آخر، من صفحة الويب)، سيؤدي هذا الطلب إلى بدء حدث fetch في عامل الخدمة.

  • إذا استدعيت add() داخل مشغّل الخدمات (ربما داخل معالج حدث آخر)، لن يؤدي الطلب إلى تنشيط معالج fetch لمشغّل الخدمات. سيتم جلب الرموز مباشرةً، بدون أي تدخل من خدمة Worker. ضع هذا في الاعتبار إذا كانت الرموز تعتمد على معالِج fetch، ربما لأنّها لا تظهر إلا في ذاكرة التخزين المؤقت المحلية وليس على الشبكة. إذا كان الأمر كذلك، تأكَّد من عدم الاتصال بـ add() إلا من سياق window.

إدراج محتوى الفهرس

تُرجع الطريقة getAll() وعدًا بقائمة قابلة للتكرار للإدخالات المفهرَسة والبيانات الوصفية لها. ستتضمّن الإدخالات المعروضة جميع البيانات المحفوظة باستخدام add().

const entries = await registration.index.getAll();
for (const entry of entries) {
  // entry.id, entry.launchUrl, etc. are all exposed.
}

إزالة العناصر من الفهرس

لإزالة عنصر من الفهرس، استخدِم delete() مع id للعنصر الذي تريد إزالته:

await registration.index.delete('article-123');

لا يؤثّر استدعاء delete() إلا في الفهرس. ولا يؤدي ذلك إلى حذف أي محتوى من ذاكرة التخزين المؤقت.

معالجة حدث حذف مستخدم

عندما يعرض المتصفّح المحتوى المفهرَس، قد يتضمّن واجهة مستخدم خاصة به تتضمّن عنصر قائمة حذف، ما يمنح المستخدمين فرصة للإشارة إلى أنّه انتهى بهم الاطّلاع على المحتوى المفهرَس سابقًا. في ما يلي شكل واجهة الحذف في الإصدار 80 من Chrome:

عنصر القائمة "حذف"

عندما يختار أحد المستخدمين عنصر القائمة هذا، سيتلقّى عامل الخدمة في تطبيق الويب حدث contentdelete. على الرغم من أنّ معالجة هذا الحدث اختيارية، إلا أنّها توفّر فرصة لخدمة Worker "لتنظيف" المحتوى، مثلملفّات الوسائط التي تم تخزينها مؤقتًا على الجهاز، والتي أشار أحد المستخدمين إلى أنّه انتهى منها.

لست بحاجة إلى استدعاء registration.index.delete() داخل معالج contentdelete. إذا تم تشغيل الحدث، سيُجري المتصفّح عملية حذف ملف الفهرس المعنيّ.

self.addEventListener('contentdelete', (event) => {
  // event.id will correspond to the id value used
  // when the indexed content was added.
  // Use that value to determine what content, if any,
  // to delete from wherever your app stores it—usually
  // the Cache Storage API or perhaps IndexedDB.
});

ملاحظات حول تصميم واجهة برمجة التطبيقات

هل هناك مشكلة في واجهة برمجة التطبيقات أو لا تعمل على النحو المتوقّع؟ أم هل هناك عناصر ناقصة تحتاجها لتنفيذ فكرتك؟

يمكنك الإبلاغ عن مشكلة في مستودع GitHub الذي يتضمّن شرحًا لواجهة برمجة التطبيقات Content Indexing API، أو إضافة ملاحظاتك إلى مشكلة حالية.

هل هناك مشكلة في التنفيذ؟

هل رصدت خطأ في عملية تنفيذ Chrome؟

أبلِغ عن خطأ على الرابط https://new.crbug.com. وأدرِج أكبر عدد ممكن من التفاصيل وتعليمات بسيطة لإعادة إنتاج الخطأ، واضبط المكوّنات على Blink>ContentIndexing.

هل تخطّط لاستخدام واجهة برمجة التطبيقات؟

هل تخطّط لاستخدام Content Indexing API في تطبيق الويب؟ يساعد الدعم العلني Chrome في تحديد الأولويات للميزات، ويُظهر لموفّري المتصفّحات الآخرين مدى أهمية إتاحة الميزات للجميع.

  • أرسِل تغريدة إلى ‎@ChromiumDev باستخدام الهاشتاغ #ContentIndexingAPI وتقدِّم تفاصيل عن مكان استخدامك للميزة وطريقة استخدامك لها.

ما هي بعض الآثار المترتبة على أمان المحتوى وخصوصيته من خلال فهرسته؟

يمكنك الاطّلاع على الإجابات التي تم تقديمها استجابةً لاستبيان الأمان والخصوصية الصادر عن W3C. إذا كان لديك مزيد من الأسئلة، يُرجى بدء مناقشة من خلال مستودع GitHub الخاص بالمشروع.

الصورة الرئيسية لأحد أعمال "مكسيم كاهارليتسكي" على Unsplash.