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

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

ما هي Content Indexing API؟

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

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

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

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

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

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

أمثلة واقعية

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

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

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

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

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

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

ما نوع عناوين 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 لدى مشغّل الخدمة. سيتم استرجاع الرموز مباشرةً، بدون أي تدخُّل من مشغّل الخدمات. يُرجى أخذ ذلك في الاعتبار إذا كانت الرموز تعتمد على معالج 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() إلا في الفهرس. ولا يحذف أي شيء من ذاكرة التخزين المؤقت.

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

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

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

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

لا تحتاج إلى طلب الرمز 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 الخاص بالمشروع.

صورة رئيسية من تصوير "ماكسيم كاهارليتسكي" في قناة UnLaunch