البحث في الموقع
المحتوى عن 'دون اتصال'.
-
تحدثنا في الجزء الأول من هذا الدرس عن أساسيات التخزين المحلي، وسنستمر في مشوارنا مع تطبيقات الويب التي تعمل دون اتصال، وسننشِئ مثالًا عمليًا عليها. تسلسل الأحداث تحدثنا إلى الآن عن تطبيقات الويب التي تعمل دون اتصال، وعن ملف manifest للتخزين المؤقت، وعن مخزن التطبيق (appcache) بشكلٍ مبهم، وكأن الأمر يجري بطريقةٍ سحريةٍ. حيث تُنزَّل الملفات، وتقوم المتصفحات بمهامها على أتمِّ وجه، وكل شيء يعمل عملًا سليمًا! لكننا نتحدث هنا عن تطوير تطبيقات الويب، فلا يعمل أيّ شيءٍ من تلقاء نفسه. بدايةً، لنتكلم عن تسلسل الأحداث، تحديدًا أحداث DOM. عندما يزور متصفحك صفحةً تُشير إلى ملف manifest، فسيُطلِق سلسلةً من الأحداث في كائن window.applicationCache؛ أعلم أنَّ هذا قد يبدو معقدًا، لكن ثق بي، هذه أبسط نسخة تمكنت من كتابتها والتي لا تهمل أيّة معلومةٍ مهمةٍ. 1. بعد أن يلاحظ المتصفح خاصية manifest في عنصر <html>، فسيُطلِق الحدث checking مباشرةً (جميع الأحداث المذكورة هنا ستُفعَّل في الكائن window.applicationCache)، سيُفعَّل الحدث checking دومًا، حتى لو زرتَ هذه الصفحة من قبل أو كانت هنالك صفحاتٌ أخرى تشير إلى نفس ملف manifest. 2. إن لم يتعامل متصفحك مع ملف manifest المُحدَّد من قبل… سيُطلِق الحدث downloading، ثم سيبدأ بتنزيل الموارد المذكورة في ملف manifest للتخزين المؤقت. أثناء التنزيل، سيُطلِق متصفحك الحدث progress بين الحين والآخر، الذي يحتوي على معلوماتٍ عن عدد الملفات التي نُزِّلَت. بعد إكمال تنزيل جميع الموارد المذكورة في ملف manifest بنجاح، سيُطلِق المتصفح الحدث النهائي cached الذي يُشير إلى أنَّ تطبيق الويب قد خُزِّن مؤقتًا بشكلٍ كامل، وهو جاهز لكي يُستخدم دون اتصال. 3. في المقابل، إن زرتَ هذه الصفحة أو أي صفحة أخرى تُشير إلى إلى نفس ملف manifest من قبل، فسيعلم متصفحك عن ملف manifest؛ فربما خزَّن بعض الموارد في مخزن التطبيق (appcache)، وربما خزَّن كامل التطبيق. إذًا السؤال الآن هو: هل تغيّر ملف manifest منذ آخر مرة تحقق فيها المتصفح من ذلك؟ إذا كان الجواب: لا، لم يتغير ملف manifest؛ فسيُطلِق متصفحك الحدث noupdate، ولن يحتاج إلى اتخاذ خطواتٍ إضافية. إذا كان الجواب: نعم، تغيّر ملف manifest؛ فسيطلِق متصفحك الحدث downloading ويُعيد تنزيل كلُ موردٍ موجودٍ في ملف manifest. أثناء التنزيل، سيُطلِق متصفحك الحدث progress بين الحين والآخر، الذي يحتوي على معلومات عن عدد الملفات التي نُزِّلَت. بعد إعادة تنزيل كل الموارد الموجودة في ملف manifest بنجاح، سيُطلِق المتصفح الحدث النهائي updateready الذي يُشير إلى أنَّ النسخة الجديدة من تطبيق الويب قد خُزِّنت مؤقتًا بشكلٍ كامل، وهي جاهزة لكي تُستخدم دون اتصال. لكن انتبه إلى أنَّ النسخة الحديثة لن تُستعمَل فورًا، فلا تُبدَّل النسخة القديمة آنيًا، لكنك تستطيع استخدام النسخة الجديدة دون إجبار المستخدم على إعادة تحميل الصفحة باستدعاء الدالة window.applicationCache.swapCache() يدويًا. إذا حدث أي شيء بشكلٍ خاطئ في أي نقطة في هذه المرحلة، فسيُطلِق متصفحك الحدث error وسيتوقف. هذه هي قائمة مختصرة بالأشياء التي قد تُسبِّب المشكلة: أعاد ملف manifest رسالة الخطأ HTTP 404 (أي Page Not Found) أو 410 (أي Permanently Gone). عُثِرَ على ملف manifest ولم يتغيّر، لكن فشل تنزيل صفحة HTML التي تُشير إلى الملف. تغيّر ملف manifest أثناء التحديث. عُثِرَ على ملف manifest وقد تغيّر، لكن المتصفح قد فشل بتنزيل أحد الموارد المذكورة فيه. تنقيح الأخطاء أريد أن أشير إلى نقطتين مهمتين هنا، أولهما هو شيءٌ قرأتَه لتوِّك لكنني متأكدٌ تمامًا أنَّك لم تعره اهتمامك، لذا دعني أكرره: إذا فشل تنزيل أحد الموارد الموجودة في ملف manifest تنزيلًا سليمًا، فستفشل عملية التخزين المؤقت لتطبيق الويب الذي يعمل دون اتصال بالكليّة، وسيُطلِق المتصفح الحدث error، لكن ليس هنالك أيّة إشارات إلى ماهية المشكلة. وهذا ما يجعل تنقيح (debugging) تطبيقات الويب التي تعمل دون اتصال معقدةً ومزعجةً أكثر من المعتاد. النقطة الثانية هي ليست –إذا ابتغينا الدقة التقنية– خطأً، لكنها ستبدو وكأنها علِّةٌ خطيرةٌ في المتصفح إلى أن تعلم ما الذي يجري. لهذه النقطة علاقةٌ بآليةِ تحققِ متصفحكَ فيما إذا تغيّر ملف manifest. وهي عمليةٌ تتألف من ثلاثِ خطواتٍ. هذه العملية مملةٌ لكنها مهمةٌ، لذا انتبه جيدًا لما سأتلوه عليك. سيسأل متصفحك –عبر البنى الهيكلية الاعتيادية في HTTP– إذا انتهت صلاحية التخزين المؤقت لملف manifest. وكما في بقية الملفات التي تُخدَّم عبر HTTP، سيُضمِّن خادوم الويب عندك بشكلٍ اعتيادي بعض المعلومات حول الملف في ترويسات HTTP. بعض تلك الترويسات (Expires و Cache-Control) تخبِر متصفحك كيف يُسمَح له بتخزين الملف مؤقتًا دون سؤال الخادوم إذا تغيِّر أم لا. لا علاقة لهذه النوع من التخزين بتطبيقات الويب التي تعمل دون اتصال؛ وهو يحدث تقريبًا لكل صفحة HTML أو صفحة أنماط CSS أو سكربتٍ ما أو صورةٍ أو أي موردٍ آخر على الويب. إذا انتهت صلاحية ملف manifest المؤقت (وفقًا لترويسات HTTP الخاصة به)، فسيسأل متصفحُك الخادومَ إذا كانت هنالك نسخةٌ جديدةٌ من الملف؛ فإن وجِدَت، فسيُنزِّلها المتصفح. وللقيام بهذا، سيُرسِل متصفحك طلبية HTTP التي تتضمَّن تاريخ آخر تعديل لملف manifest المُخزَّن مؤقتًا، وهو نفسه الذي أرسله الخادوم في جواب HTTP (HTTP response) في آخر مرّة نزَّل فيها متصفحك ملف manifest. إذا قال خادوم الويب أنَّ ملف manifest لم يتغير منذ ذاك الوقت، فسيُعيد الخادوم حالة 304 (أي Not Modified). أكرِّر أنَّ هذا لا علاقة له بتطبيقات الويب التي تعمل دون اتصال، وهو يحدث لكل نوع من أنواع الموارد الموجودة في الويب. إذا ظنَّ خادوم الويب أنَّ ملف manifest قد تغيّر منذ ذاك التاريخ، فسيُعيد الحالة HTTP 200 (أي OK) متبوعةً بمحتويات الملف الجديد بالإضافة إلى ترويسات Cache-Control جديدة وتاريخ جديد لآخر تعديل، لذا ستعمل الخطوتان 1 و 2 بشكلٍ سليم في المرة القادمة (بروتوكول HTTP جميل جدًا؛ إذ تُخطِّط خواديم الويب للمستقبل دائمًا، فإن كان على خادوم الويب إرسال ملفٍ إليك، فسيفعل ما بوسعه لكي يتأكَّد أنَّه لن يحتاج إلى إرساله لك مرتين دون داعٍ). بعد تنزيل ملف manifest الجديد، سيقارن المتصفح المحتويات مع النسخة التي نزَّلها آخر مرة. إذا كانت محتويات ملف manifest مماثلةً لمحتويات آخر نسخة، فلن يُعيد متصفحك تنزيل أيٌّ من الموارد المذكورة في الملف. قد تعترض إحدى الخطوات السابقة طريقك أثناء تطويرك واختبارك لتطبيق الويب الذي يعمل دون اتصال، على سبيل المثال، لنقل أنَّك أنشأتَ نسخةٌ من ملف manifest، ثم بعد 10 دقائق أدركت أنَّك تحتاج إلى إضافة مورد آخر إلى الملف. لا توجد مشكلة، صحيح؟ أضفت سطرًا جديدًا وجربت التطبيق، لكنه لم يعمل! إليك ما حدث: عندما أعدت تحميل الصفحة، لاحظ المتصفح خاصية manifest، وأطلق الحدث checking، لكنه لم يفعل شيئًا… أصرَّ متصفحك بعنادٍ أنَّ ملف manifest لم يتغير. لماذا؟ لأنَّ خادوم الويب –افتراضيًا– مضبوطٌ للطلب من المتصفحات أن تُخزِّن الملفات الثابتة مؤقتًا لعدِّة ساعات (وذلك عبر ترويسات Cache-Control في بروتوكول HTTP). وهذا يعني أنَّ متصفحك سيبقى عالقًا في الخطوة رقم 1 من الخطوات الثلاث السابقة. من المؤكَّد أنَّ خادوم الويب يعرف أنَّ الملف قد تغيّر، لكن متصفحك لن يحاول سؤال خادوم الويب. لماذا؟ لأنَّه في آخر مرة نزَّل متصفحك فيها ملف manifest، طلب الخادوم منه أن يُخزِّن الملف مؤقتًا لعدِّة ساعات، لكن متصفحك حاول إعادة طلب ذاك الملف بعد 10 دقائق. دعني أوضِّح لك أنَّ هذه ليست علّة وإنما ميزة. إذ يعمل كل شيءٍ كما يجب. إن لم تكن هنالك طريقة لخواديم الويب (وللخواديم الوسيطة [proxies]) لتخزين الملفات مؤقتًا، فسينهار الويب بين ليلةٍ وضحاها. لكن هذا ليس عزاءً لك بعد أن قضيت عدِّة ساعات محاولًا معرفة لماذا لم يلاحظ متصفحك أنَّ ملف manifest قد تعدَّل (من الطريف إن كنت قد انتظرت فترةً كافيةً ثم أعدتَ تحميل الصفحة فسيعمل الملف بشكلٍ سحري! ذلك لأنَّ فترة صلاحية الملف قد انتهت، كما قد حُدِّدَ لها تمامًا). هذا ما عليك فعله فوريًا: إعادة ضبط خادوم الويب عندك لكي لا يُخزَّن ملف manifest مؤقتًا عبر بروتوكول HTTP. إذا كنتَ تستعمل خادوم ويب مبني على أباتشي، فكل ما عليك فعله هو إضافة السطرين الآتيين إلى ملف .htaccess: ExpiresActive On ExpiresDefault "access" التعليمات السابقة ستُعطِّل التخزين المؤقت لكل ملف في ذاك المجلد وفي جميع المجلدات الفرعية، ومن المُرجَّح أنَّك لا تريد فعل هذا في خادومٍ إنتاجي؛ لذا عليك إما أن تضع التعليمات السابقة ضمن تعليمة <Files> لكي تؤثِّر على ملف manifest فقط، أو تُنشِئ مجلدًا فرعيًا لا يحتوي إلا على ملف manifest وملف .htaccess فقط. وكالمعتاد، تختلف تفاصيل الضبط من خادومٍ إلى آخر، لذا راجع توثيق خادوم الويب الذي تستعمله لتفاصيلٍ حول كيفية التحكم بترويسات التخزين المؤقت لبروتوكول HTTP. بعد أن تُعطِّل التخزين المؤقت الخاص ببروتوكول HTTP على ملف manifest، ربما تواجهك مشكلة أخرى في أنَّك قد عدَّلت في أحد الموارد التي ستُخزَّن في مخزن التطبيق (appcache) لتُستعمَل دون اتصال، لكنها بقيت تملك نفس عنوان URL في خادومك. هنا ستعترض الخطوة رقم 2 من الخطوات الثلاث السابقة طريقك. إذا لم يتغير محتوى ملف manifest، فلن يلاحظ المتصفح أنَّ أحد الموارد المُخزَّنة مسبقًا قد تغيّر. ألقِ نظرةً إلى المثال الآتي: CACHE MANIFEST # rev 42 clock.js clock.css إذا عدِّلتَ ملف الأنماط clock.css وجربت التطبيق، فلن تلاحظ وجود التعديلات التي أجريتها، وذلك لأنَّ ملف manifest نفسه لم يُعدَّل. في كل مرة تُجري فيها تعديلًا لموردٍ ما في تطبيق الويب الذي يعمل دون اتصال، فعليك أن تُعدِّل ملف manifest نفسه. وهذا بسيطٌ جدًا، فلا يلزمك إلا تغييرُ حرفٍ وحيد. أسهل طريقة وجدتها لفعل هذا هو تضمين تعليق فيه رقم النسخة أو المراجعة (revision). غيّر رقم النسخة الموجود في التعليق، ثم سيلاحظ متصفحك أنَّ محتوى الملف قد تغيّر وسيعيد تنزيل كل الموارد المذكورة فيه. CACHE MANIFEST # rev 43 clock.js clock.css لننشِئ واحدًا! هل تتذكر لعبة الضامة التي برمجناها في درس canvas ثم حسّنّاها لاحقًا بحفظنا للتحركات عبر التخزين المحلي؟ ما رأيك أن نجعل اللعبة تعمل دون اتصال. علينا أن نُنشِئ ملف manifest يحتوي على قائمة بجميع الموارد التي تحتاج لها اللعبة. حسنًا، هنالك صفحة HTML رئيسية، وملف JavaScript وحيد الذي يحتوي على شيفرة اللعبة. لا توجد صور، لأننا رسمنا كل شيءٍ برمجيًا عبر الواجهة البرمجية لعنصر canvas. وجميع أنماط CSS موجودة في عنصر <style> في أعلى صفحة HTML. ها هو ذا ملف manifest الخاص باللعبة: CACHE MANIFEST halma.html ../halma-localstorage.js كلمة عن المسارات: أنشأتُ مجلدًا فرعيًا باسم offline/ في مجلد examples/، وملف manifest السابق موجودٌ هناك في المجلد الفرعي. ولأنَّ صفحة HTML ستحتاج إلى تعديلٍ بسيطٍ لكي تعمل دون اتصال (سآتيك به بعد دقيقة)، فأنشأتُ نسخةً منفصلةً من ملف HTML، الموجودةُ أيضًا في المجلد الفرعي offline/، ولعدم وجود أيّة تعديلات على شيفرة JavaScript منذ أن أضفنا دعمًا للتخزين المحلي، فسأستعمل ملفات .js نفسها، الموجودة في المجلد الأب (examples/). ستبدو المسارات كالآتي: /examples/localstorage-halma.html /examples/halma-localstorage.js /examples/offline/halma.manifest /examples/offline/halma.html نريد الإشارة إلى ملفين في ملف manifest للتخزين المحلي (/examples/offline/halma.manifest)، أولهما هو النسخة التي تعمل دون اتصال لملف HTML (/examples/offline/halma.html) ولأن كلا الملفين في نفس المجلد، فمن الممكن ذكره في ملف manifest دون وجود سابقة للمسار. أما ثانيهما، فهو ملف JavaScript الموجود في المجلد الأب (/examples/halma-localstorage.js)، ويجب استخدام المسارات النسبية في ملف manifest: ../halma-localstorage.js، وهذا مشابهٌ لاستعمالك لعنوان URL نسبي في خاصية <img src>. يمكنك أيضًا استعمال المسارات المطلقة (absolute paths، تلك التي تبدأ من المجلد الجذر للموقع) أو حتى عناوين URL المطلقة (التي تُشير إلى موارد موجودة على نطاقات أخرى). علينا إضافة خاصية manifest في ملف HTML لكي تُشير إلى ملف manifest للتخزين المؤقت: <!DOCTYPE html> <html lang="en" manifest="halma.manifest"> هذا كل ما عليك فعله! عندما تزور صفحة اللعبة التي تعمل دون اتصال بمتصفح حديث، فسينزِّل ملف manifest المُشار إليه في خاصية manifest ثم سيبدأ بتنزيل جميع الموارد الموجودة فيه ويضعها في مخزن التطبيق (appcache). ومن هنا ستتولى شيفرة الصفحة الأمر في كل مرة تزور فيها الصفحة. يمكنك اللعب دون اتصال وستُخزَّن بيانات اللعبة محليًا، لذا ستستطيع أن تُغلِق اللعبة ثم تعود إليها متى شئت. كلمة أخيرة أعلنت W3C أخيرًا أنَّها ستزيل هذه الميزة من معيار HTML5، إلا أنَّ هذه العملية ستستغرق وقتًا طويلًا. ونصحت W3C باستخدام Service Workers بدلًا منها. المشكلة أنَّ ميزة Service Workers غير مدعومة من الغالبية العظمى من المتصفحات، والمتصفحات التي تتواجد فيها ميزة Service Workers تدعمها دعمًا جزئيًا فقط. تركت W3C المطورين بين المطرقة والسندان، لكنني أرى أنَّ عليك الاستمرار في استخدام هذه الميزة، مع متابعة أخبار دعم Service Workers لتنتقل إليها في المستقبل. مصادر إضافية المعايير: Offline web applications في مواصفة HTML5 توثيقٌ من صانعي المتصفحات: Offline resources in Firefox HTML5 offline application cache، التي هي جزءٌ من Safari client-side storage and offline applications programming guide الدروس التعليمية: Gmail for mobile HTML5 series: using appcache to launch offline - part 1 Gmail for mobile HTML5 series: using appcache to launch offline - part 2 Gmail for mobile HTML5 series: using appcache to launch offline - part 3 Debugging HTML5 offline application cache an HTML5 offline image editor and uploader application ترجمة -وبتصرّف- لفصل Offline Web Applications من كتاب Dive Into HTML5 لمؤلفه Mark Pilgrim. اقرأ أيضًا المقال التالي: النماذج (Forms) في HTML5 المقال السابق: تطبيقات الويب التي تعمل دون اتصال – الجزء الأول النسخة العربية الكاملة من كتاب نحو فهم أعمق لتقنيات HTML5
-
ما هي تطبيقات الويب التي تعمل دون اتصال؟ يبدو الأمر من الوهلة الأولى كأنَّ هنالك تضاربًا في المفاهيم. فهل هي صفحات الويب التي تنزِّلها ثم تفتحها بعد ذلك؟ لكن التنزيل يتطلب اتصالًا شبكيًا، فكيف ستستطيع تنزيل الصفحة عندما لا تكون متصلًا؟ لن تستطيع فعل ذلك بكل تأكيد، لكنك تستطيع تنزيل الصفحة عندما تكون متصلًا بالشبكة، وهذه هي آلية عمل تطبيقات HTML5 التي تعمل دون اتصال (offline web applications). بأبسط الكلمات: تطبيق الويب الذي يعمل دون اتصال هو قائمةٌ بروابط URL التي تُشير إلى ملفات HTML أو CSS أو JavaScript أو الصور أو أيّ موردٍ آخر. تُشير الصفحة الرئيسية إلى تلك القائمة التي تُسمى «ملف manifest» الذي هو ملفٌ نصيٌ موجودٌ في مكانٍ ما على خادوم الويب، وسيقرأ متصفح الويب الذي يدعم تشغيل تطبيقات الويب دون اتصال قائمةَ روابطِ URL الموجودةَ في ملف manifest، ثم يُنزِّل تلك الموارد (resources)، ثم يُخزِّنها تخزينًا مؤقتًا محليًا (local cache)، ثم سيُحدِّث النسخ المحلية منها تلقائيًا في حال تغيرت. وعندما يحين وقت محاولتك الوصول إلى تطبيق الويب دون اتصالٍ شبكي، فسيحاول متصفحك عرض النسخة المُخزَّنة محليًا تلقائيًا. ومن هذه النقطة، سيُلقى الحِمل على عاتِقِكَ تمامًا –كمطوِّر ويب–؛ فهنالك رايةٌ (flag) في DOM تخبرك إذا كان المتصفح متصلًا بالشبكة أم لا، وهنالك أحداث (events) تُفعَّل عندما تتغير حالة الوصول إلى الشبكة (أي لو كنتَ تعمل دون اتصال، ثم توفَّر لديك بعد دقيقةٍ اتصالٌ شبكي؛ أو بالعكس). لكن إن كان تطبيقُك يولِّد بياناتٍ أو يحفظها، فالأمر متروكٌ لك لتخزين البيانات محليًا عندما لا تكون متصلًا بالشبكة ثم تزامنها مع الخادوم البعيد بعد أن تستعيد اتصالك به. بعبارةٍ أخرى، تمكّنك HTML من جعل تطبيقك يعمل دون اتصال، لكن ما يفعله تطبيقك في هذه المرحلة عائدٌ إليك تمامًا. المتصفحات التي تدعم هذه الخاصية IE Firefox Safari Chrome Opera iPhone Android 10+ 3.5+ 4.0+ 5.0+ 10.6+ 2.1+ 2.0+ ملف Manifest يتمحور تطبيق الويب الذي يعمل دون اتصال حول ملف manifest للتخزين المؤقت. إذًا ما هو ملف manifest؟ هو قائمة بكل الموارد (resources) التي يحتاج لها تطبيق الويب لكي يستطيع المستخدم الوصول إليه وهو غير متصلٍ بالشبكة. وعليك أن تُشير إلى ملف manifest باستعمالك لخاصية manifest في عنصر <html> لتمهيد الطريق لعملية تنزيل وتخزين تلك الموارد تخزينًا مؤقتًا. <!DOCTYPE HTML> <html manifest="/cache.manifest"> <body> ... </body> </html> يمكن أن يتواجد ملف manifest للتخزين المؤقت في أي مكان في خادوم الويب عندك، لكن يجب أن يُخدَّم بنوع text/cache-manifest؛ إذا كنتَ تستعمل خادوم ويب يعتمد على أباتشي (Apache)، فمكن المرجَّح أنَّ كل ما عليك فعله هو إضافة تعليمة AddType في ملف .htaccess في المجلد الجذر الذي يُخدَّم منه تطبيق الويب: AddType text/cache-manifest .manifest تأكَّد أنَّ اسم ملف manifest للتخزين المؤقت ينتهي باللاحقة .manifest؛ إن كنتَ تستعمل خادوم ويب آخر أو ضبطًا مختلفًا لأباتشي، فراجع التوثيق الخاص بالخادوم لمزيدٍ من المعلومات حول التحكم في ترويسة Content-Type. حسنًا، على كل صفحة من صفحات HTML أن تُشير إلى ملف manifest للتخزين المؤقت، ويجب أن يُخدَّم ملف manifest بترويسة Content-Type مناسبة. لكن ماذا يوجد داخل ملف manifest؟ ها قد بدأت الإثارة. أول سطر من أي ملف manifest هو: CACHE MANIFEST وبعد هذا السطر، ستُقسَّم جميع ملفات manifest إلى ثلاثة أقسام: قسم «explicit»، وقسم «fallback» وقسم «online whitelist». لدى كل قسم ترويسةٌ مذكورةٌ في سطرٍ خاصٍ بها؛ وإن لم يحتوي ملف manifest على أيّة ترويسات، فهذا يعني ضمنيًا أنَّ كل الموارد المذكورة في الملف موجودةٌ في القسم «explicit». لا تحاول أن تطيل التفكير في الاصطلاحات السابقة، خشية أن ينفجر رأسك من الصداع. هذا ملف manifest سليمُ البنية، ويحتوي على ثلاثة موارد: ملف CSS، وملف JavaScript، وصورة JPEG. CACHE MANIFEST /clock.css /clock.js /clock-face.jpg لا يحتوي ملف manifest السابق على ترويسات للأقسام، لذا ستكون جميع الموارد المذكورة فيه موجودة في قسم «explicit» افتراضيًا. ستُنزَّل الموارد المذكورة في قسم «explicit» وتُخزَّن تخزينًا مؤقتًا محليًا، وستُستعمَل مكان نظيراتها الموجودة على الشبكة في حال كان المستخدمُ غيرَ متصلٍ. وبهذا –وعند تحميل ملف manifest للتخزين المؤقت– سينُزِّل متصفح الويب الملفات clock.css و clock.js و clock-face.jpg من المجلد الجذر لخادوم الويب، ثم إذا أزلتَ مقبس الشبكة وأعدتَ تحديث الصفحة، فستبقى كل تلك الموارد متوفرةً دون اتصال. قسم NETWORK هذا مثالٌ أكثر تعقيدًا. لنقل أنَّك تريد من تطبيق الساعة الذي أنشأته أن يتتبع الزوار باستخدام سكربت tracking.cgi الذي سيُحمَّل ديناميكيًا في خاصية <img src>، إلا أنَّ تخزين هذا الملف تخزينًا مؤقتًا سيؤثر سلبًا على غرض ذاك السكربت (الذي هو تتبع المستخدمين آنيًا)، لذا لا يجب أبدًا تخزين هذا المورد مؤقتًا ولا يجوز أن يُتاح دون اتصال. هذه هي طريقة فعل ذلك: CACHE MANIFEST NETWORK: /tracking.cgi CACHE: /clock.css /clock.js /clock-face.jpg ملف manifest السابق يحتوي على ترويسات للأقسام، فالسطر الذي يحتوي على NETWORK: هو بداية قسم «online whitelist»، والموارد المذكورة في هذا القسم لن تُخزَّن محليًا ولن تتوفر دون اتصال (محاولة تحميلها عند عدم توفر اتصال ستؤدي إلى خطأ). أما السطر CACHE: فهو بداية قسم «explicit»، وبقية ملف manifest مماثلة للمثال السابق، حيث سيُنزَّل وسيُخزَّن كل مورد من الموارد المذكورة محليًا وسيُتاح للاستعمال دون اتصال. قسم FALLBACK هنالك نوعٌ آخر من الأقسام في ملف manifest: قسمfallback، الذي تُعرِّف فيه البدائل عن الموارد الموجودة على الشبكة التي –لسببٍ من الأسباب– لا يمكن تخزينها مؤقتًا أو لم يتم ذلك بنجاح. توفِّر مواصفة HTML5 حلًا ذكيًا لطريقة استخدام قسم fallback: CACHE MANIFEST FALLBACK: / /offline.html NETWORK: * ماذا يفعل المثال السابق؟ أولًا، لنأخذ مثالًا موقعًا يحتوي ملايين الصفحات مثل ويكيبيديا؛ لا تستطيع تنزيل كامل الموقع، ومن المؤكد أنَّك لا ترغب بذلك. لكن لنقل أنَّك تريد أن تأخذ جزءًا منه وتجعله متوفرًا دون اتصال؛ لكن كيف ستقرر ما هي الصفحات التي تحتاج إلى تخزينها مؤقتًا؟ ماذا عن: كل صفحة زرتها في موقع ويكيبيديا –الذي افترضنا جدلًا أنَّه يدعم التشغيل دون اتصال– ستُنزَّل وستخزَّن مؤقتًا. وهذا يتضمن كل مُدخَلة من مدخلات الموسوعة التي زرتها، وكل صفحة نقاش (أي المكان الذي تتناقش فيه عن مُدخَلة معيّنة)، وكل صفحة تحرير (أي تلك الصفحة التي تُجري فيها تعديلاتٍ إلى مُدخلةٍ ما). هذا ما سيفعله ملف manifest السابق: لنفترض أنَّ كل صفحة HTML (صفحة المُدخلة أو النقاش أو التعديل أو تأريخ الصفحة) في ويكيبيديا تُشير إلى ملف manifest السابق؛ فعندما تزور أي صفحة تُشير إلى ملف manifest فسيقول متصفحك: «مهلًا، هذه الصفحة جزءٌ من تطبيق الويب يعمل دون اتصال، لكن هل أعرف شيئًا عن هذا التطبيق؟» إن لم يُنزِّل متصفحك ملف manifest المُحدَّد من قبل قط، فسيهِّيء «مخزن جديد للتطبيق» (appcache، اختصار للعبارة «application cache»)، وسيُنزِّل جميع الموارد المذكورة في ملف manifest، ثم سيُضيف الصفحة الحالية إلى مخزن التطبيق (appcache). إن كان يعرف متصفحك ملف manifest من قبل، فسيُضيف الصفحة الحالية إلى مخزن التطبيق (appcache) الموجود مسبقًا. وفي كلا الحالتين ستُضاف الصفحة التي زرتها إلى مخزن التطبيق. وهذا مهمٌ لأنَّه يعني أنَّك تستطيع بناء تطبيق ويب يُضيف الصفحات التي يزورها المستخدم تلقائيًا إلى مخزنه. فلستَ بحاجةٍ إلى وضع كل صفحة من صفحات HTML في ملف manifest للتخزين المؤقت. انظر الآن إلى قسم fallback في ملف manifest السابق، الذي يحتوي على سطرٍ وحيدٍ. القسم الأول من السطر (الذي يقع قبل الفراغ) ليس عنوان URL، وإنما نمط URL (URL pattern)، حيث سيُطابِق المحرف / أي صفحة في موقعك وليس الصفحة الرئيسية فقط. فعندما تحاول زيارة صفحة ما عندما تكون غيرَ متصلٍ بالشبكة، فسيبحث متصفحك عنها في مخزن التطبيق (appcache)، فإن وجد المتصفحُ الصفحةَ في مخزن التطبيق (ﻷنك زُرتَها عندما كنتَ متصلًا بالشبكة، ومن ثم أُضيفَت الصفحة إلى مخزن التطبيق [appcache] في ذات الوقت)، فسيعرض المتصفح النسخة المُخزَّنة من الصفحة محليًا؛ إما إذا لم يجد متصفحك الصفحة في مخزن التطبيق، فبدلًا من عرض رسالة الخطأ، فسيعرض الصفحة /offline.html التي تُمثِّل القسم الثاني في السطر المذكور في قسم fallback. في النهاية، لننظر إلى قسم الشبكة (network). يحتوي قسم الشبكة في ملف manifest السابق على سطرٍ فيه محرف وحيد (*)، هذا المحرف له معنىً خاص في قسم الشبكة. وهو يُدعى «online whitelist wildcard flag» وهي طريقة منمّقة لقول أنَّ كل شيءٍ غير موجودٍ في مخزن التطبيق (appcache) سيُنزَّل من عنوان الويب الأصلي لطالما هنالك اتصالٌ شبكيٌ بالإنترنت. هذا مهمٌ لتطبيقات الويب التي تعمل دون اتصال التي لا نريد تنزيلها كل صفحاتها ومواردها، وهذا يعني أنَّه أثناء تصفحك لموقع ويكيبيديا –الذي افترضنا جدلًا أنَّه يدعم العمل دون اتصال– مع اتصالٍ بالإنترنت، فسيحمِّل المتصفح الصور ومقاطع الفيديو والموارد الأخرى المضمَّنة بشكلٍ اعتيادي، حتى ولو كانت في نطاقٍ (domain) مختلف (هذا الأمر شائعٌ في المواقع الكبرى حتى لو لم تكن جزءًا من تطبيق ويب يعملُ دونَ اتصالٍ. صفحات HTML تولَّد وتُخدَّم محليًا في تلك الخواديم، لكن الصور والفيديو تُخدَّم عبر CDN في نطاقٍ آخر). لكن دون هذا المحرف البديل (wildcard)، فسيتصرّف تطبيق ويكيبيديا الذي افترضنا أنَّه يعمل دون اتصال تصرفاتٍ غريبة عندما تكون متصلًا بالشبكة. بشكلٍ خاص: لن يستطيع تنزيل أي صور أو مقاطع فيديو مخزَّنة على نطاقٍ خارجي. هل هذا المثال كاملٌ؟ لا، لأنَّ ويكيبيديا أكثر من مجرد صفحات HTML. فهي تستعمل موارد CSS و JavaScript وصور مشتركة في كل صفحة. فيجب أن تُذكَر تلك الموارد بشكلٍ صريحٍ في قسم CACHE: من ملف manifest، لكي تُعرَض الصفحات عرضًا صحيحًا وتسلك سلوكًا سليمًا عندما تُشغَّل دون اتصال. لكن الغاية من قسم fallback تكمن عندما لا تنزِّل كامل صفحات تطبيق الويب الذي يحتوي على موارد لم تذكرها بصراحة في ملف manifest. ترجمة -وبتصرّف- لفصل Offline Web Applications من كتاب Dive Into HTML5 لمؤلفه Mark Pilgrim. اقرأ أيضًا المقال التالي: تطبيقات الويب التي تعمل دون اتصال – الجزء الثاني المقال السابق: التخزين المحلي (Local Storage) في HTML5 النسخة العربية الكاملة من كتاب نحو فهم أعمق لتقنيات HTML5