عزل التخزين لا يضمن سلامة البيانات
يمكن أن تكون ملفات تعريف المتصفح معزولة تمامًا، ومع ذلك يفقد تطبيق ويب بياناته عند امتلاء القرص أو انقطاع العملية أثناء كتابة IndexedDB. اختبار الكوكيز بين البروفايلات لا يكشف هذه الفئة من الأعطال. هذا الدليل يركز على سلامة المعاملات والاستعادة وحدود مساحة التخزين، لا على منع انتقال البيانات بين الحسابات. سنستخدم بيانات اختبار لا تحتوي معلومات حقيقية، ونقيس ما بقي بعد إعادة التشغيل وما فشل بطريقة قابلة للتفسير. لا تفترض أن نجاح عملية حفظ في واجهة الموقع يعني أن البيانات أصبحت دائمة على القرص.
تعرف على أنواع البيانات المعنية
قد يستخدم الموقع LocalStorage لإعدادات صغيرة، و IndexedDB لسجلات منظمة، و Cache Storage لطلبات وموارد محفوظة، وملفات ضمن Origin Private File System في تطبيقات تدعمه. لكل مخزن قواعد مختلفة، ولا ينبغي اعتبار جميعها ملفًا واحدًا يمكن نسخه أثناء عمل المتصفح. قد يعتمد الموقع أيضًا على خادم بعيد لمزامنة الحالة، فيختلط فقد محلي مع تأخر الشبكة. قبل الاختبار، اكتب خريطة توضح مصدر الحقيقة لكل معلومة، وهل يمكن إعادة بنائها، وما المدة المقبولة لفقد البيانات غير المتزامنة.
حدد عقد النجاح قبل التجربة
هل يجب أن تبقى كل عملية أقر المتصفح اكتمالها بعد انقطاع مفاجئ؟ وهل يجوز فقد آخر عملية لم يصل تأكيدها؟ هذه أسئلة تحتاج تعريفًا وفق التطبيق ومحرك التخزين ونظام الملفات. لا تعد المستخدم بضمان مطلق للمتانة دون دليل من المنصة. ضع معرفًا فريدًا لكل سجل تجريبي، ورقم تسلسل، وبصمة محتوى، ووقت بدء العملية ووقت تأكيدها. بعد إعادة التشغيل، قارن السجلات المؤكدة وغير المؤكدة، ولا تعتبر مجرد عدد الصفوف كافيًا؛ فقد تبقى صفوف بقيم قديمة أو ناقصة.
ما الذي تضمنه معاملة IndexedDB؟
تجمع المعاملة مجموعة عمليات قراءة وكتابة ضمن نطاق مخازن محدد، ويمكن أن تنتهي بنجاح أو تُلغى عند حدوث خطأ. لكن التفاصيل المتعلقة بوقت كتابة البيانات فعليًا إلى التخزين الدائم قد تتأثر بالمحرك ونظام التشغيل. لذلك افصل بين اكتمال المعاملة في واجهة API وبين سيناريو فقد الطاقة الحقيقي. اختبر التناسق المنطقي: إذا كتبت سجل طلب ومجموعه في معاملة واحدة، فلا ينبغي أن يظهر أحدهما دون الآخر عند الاستعادة وفق ضمانات المعاملة. لا تستخدم معاملة واحدة ضخمة بلا سبب؛ قد تزيد زمن الحجز واستهلاك الموارد.
افصل أخطاء الحصة عن أخطاء التطبيق
قد ترفض عملية تخزين بسبب QuotaExceededError أو سياسة مساحة الموقع أو نقص المساحة الفعلية أو خطأ آخر. لا تعرض كل هذه الحالات للمستخدم بعبارة «فشل الحفظ» دون تفصيل مناسب. سجّل اسم الخطأ ونوع العملية وحجم الحمولة والبيئة، مع تجنب حفظ البيانات الحساسة. قد يعرض navigator.storage.estimate تقديرات تقريبية للاستخدام والحصة، وليس عدادًا دقيقًا لبايتات القرص. لا تجعل التطبيق يعتمد على تجاوز نسبة ثابتة من الحصة قبل الكتابة؛ قد تتغير السياسة بحسب المتصفح والاستخدام.
اختبار مساحة ممتلئة دون إيذاء الجهاز
لا تملأ قرص النظام الفعلي حتى الصفر لاختبار سلوك الموقع. استخدم بيئة افتراضية أو حاوية أو قسم اختبار محدود المساحة، واحتفظ بنسخة يمكن استعادتها. أنشئ بيانات تدريجية حتى يظهر رفض كتابة، ثم تحقق من أن التطبيق يعرض رسالة مفهومة ويمنع تكرار المحاولة بلا نهاية. راقب RAM و Swap والعمليات حتى لا يتحول الاختبار إلى توقف للخدمة. إذا كانت البيئة لا تسمح بمحاكاة آمنة، اختبر معالجة الخطأ برمجيًا في طبقة التطبيق، ثم سجّل أن سيناريو امتلاء القرص الحقيقي لم يُختبر.
اختبار انقطاع العملية في اللحظة الحرجة
ابدأ سلسلة معاملات صغيرة مع تسجيل معرفاتها، ثم أنهِ عملية متصفح اختبارية بعد نقطة محددة دون إنهاء نظام التشغيل كله. عند إعادة التشغيل، افحص أي المعاملات اكتملت وأيها أُلغيت. كرر عند نقاط مختلفة: قبل بدء المعاملة، أثناء الكتابة، بعد إشارة اكتمالها، وبعد إغلاق الصفحة. لا تستخدم بروفايل إنتاجي أو حسابًا حقيقيًا. الإنهاء القسري ليس مطابقًا لفقد الكهرباء؛ قد تستمر ذاكرة التخزين المؤقت في نظام التشغيل. إذا احتجت محاكاة أعمق، استخدم بيئة افتراضية يمكن التخلص منها.
لا تنسَ Cache Storage و Service Worker
قد يعيد Service Worker صفحة من Cache Storage بعد استعادة المتصفح، بينما تكون بيانات IndexedDB أحدث أو أقدم. إذا كان التطبيق يربط نسخة واجهة معينة بمخطط قاعدة بيانات محدد، فقد تظهر أخطاء بعد تحديث غير مكتمل. اختبر نسخة التطبيق قبل التحديث وبعده، وتأكد من أن مسار الترقية لا يفترض نجاح كل كتابة. لا تحذف الكاش تلقائيًا لمجرد ظهور اختلاف؛ فقد تحتاج بعض الموارد للعمل دون اتصال. ضع خطة ترحيل وإمكانية تراجع أو إصلاح متدرج، وسجل إصدار المخطط ونسخة Service Worker عند كل تشغيل.
الاحتفاظ الدائم ليس مضمونًا تلقائيًا
توفر واجهة StorageManager وسائل للاستعلام عن حالة الاستمرارية وطلبها في بعض المتصفحات، لكن منح الطلب يعتمد على سياسات المتصفح ولا يعني حماية مطلقة من حذف المستخدم أو تلف الجهاز. لا تستخدم كلمة «دائم» في الواجهة بمعنى لا يمكن فقده أبدًا. افحص نتيجة navigator.storage.persisted ونتيجة طلب persist عند الحاجة، ثم قدم للمستخدم سياسة نسخ احتياطي واضحة للبيانات المهمة. لا تفترض أن التخزين الدائم يحل مشكلة تعارض نسختين أو فساد منطقي في التطبيق؛ هو يعالج جانبًا مختلفًا من إدارة الإزالة.
جدول مصفوفة الأعطال
قس أربع حالات على الأقل: كتابة طبيعية ثم إعادة فتح، ورفض حصة تخزين، وإنهاء عملية أثناء معاملة، وتحديث Service Worker مع ترقية قاعدة البيانات. لكل حالة تحقق من سلامة السجلات المؤكدة، ووضوح رسالة الخطأ، وإمكان الاستئناف دون تكرار أو فقد إضافي. أضف اختبارًا لتعدد التبويبات إذا كانت تشارك قاعدة البيانات نفسها؛ فقد يظهر تعارض ترقية بين إصدارين مفتوحين. لا تخلط بين خطأ ترقية مخطط وبين عطل في عزل البروفايل، فالأدلة المطلوبة مختلفة.
اختبارات تخزين منخفضة المخاطر
| كتابة طبيعية | سجلات مؤكدة بعد إعادة الفتح | أن الواجهة وحدها مصدر الحقيقة |
| نفاد الحصة | خطأ واضح بلا حلقة تكرار | دقة estimate بالبايت |
| إنهاء العملية | سلامة معاملات مكتملة | مطابقة انقطاع الطاقة |
| ترقية مخطط | اتساق الإصدارات والتبويبات | نجاح التحديث تلقائيًا |
كيف تقيس سلامة الاستعادة؟
بعد كل تشغيل تجريبي، احسب عدد المعرفات الفريدة، وقارن البصمات، وتحقق من العلاقات بين السجلات، ثم أعد تشغيل التطبيق دون كتابة جديدة لتتأكد من ثبات النتيجة. إذا كان التطبيق يستخدم طابور مزامنة إلى الخادم، اختبر عدم إرسال العملية نفسها مرتين عند الاستعادة، باستخدام مفتاح idempotency مناسب. لا تقارن فقط واجهة المستخدم، لأنها قد تعرض بيانات محفوظة في الذاكرة لم تُقرأ من التخزين. افتح جلسة جديدة أو أعد إنشاء اتصال قاعدة البيانات لتفحص البيانات المستعادة فعليًا.
التزامن بين تبويبين يزيد التعقيد
قد تفتح نافذتان من الموقع قاعدة IndexedDB نفسها، ثم تبدأ إحداهما ترقية إصدار بينما تحتفظ الأخرى باتصال قديم. تعامل مع أحداث blocked و versionchange بحسب تصميم التطبيق، وأبلغ المستخدم عند الحاجة إلى إغلاق تبويب قديم. لا تفترض أن إعادة تحميل تبويب واحد تكفي إذا كانت هناك Service Worker أو نافذة خلفية نشطة. نفذ اختبارًا متكررًا لتسلسل الترقية، ثم راجع عدم بقاء واجهة قديمة تكتب وفق مخطط غير متوافق. استخدم بيانات صغيرة وواضحة حتى تستطيع معرفة أين حدث التعارض.
ماذا يختلف بين Chrome و Electron؟
الاشتراك في Chromium لا يضمن تطابق كل سياسات التخزين أو مسارات ملفات البروفايل أو طريقة إدارة الأقسام في تطبيق Electron. قارن إصدار المحرك وإعدادات الجلسة ومسار التخزين وسياسة إنهاء العمليات قبل اتهام IndexedDB نفسه. إذا كانت هناك أقسام مؤقتة وأخرى مدعومة بالقرص، اختبر كل نوع بشكل منفصل، ولا تستنتج الاستمرارية من اسم القسم فقط. سجل مكان البيانات وحالة المجلد بعد إعادة التشغيل، لكن لا تنقل ملفات قاعدة البيانات أثناء تشغيل التطبيق إلا إذا كانت آلية النسخ موثقة وآمنة.
أخطاء تجعل التقرير مضللًا
من الأخطاء اختبار النجاح مرة واحدة ثم تعميمه، أو إعلان فساد قاعدة البيانات لأن واجهة الموقع فشلت في التحميل، أو مسح مجلد التخزين قبل جمع السجلات، أو خلط نتائج عدة بروفايلات في تقرير واحد. كذلك لا تختبر على جهاز شبه ممتلئ دون مراقبة الموارد؛ قد تتسبب العملية في تعطل تطبيقات أخرى. افصل خطأ الواجهة عن خطأ قاعدة البيانات وعن فشل المزامنة مع الخادم. احتفظ بتوقيت UTC وإصدار المتصفح ومخطط قاعدة البيانات ومعرف الاختبار، ثم أعد التجربة في بيئة ضابطة.
المصادر والقراءة المتصلة
تشرح MDN واجهة StorageManager وتقديرات الحصة والاستمرارية: https://developer.mozilla.org/en-US/docs/Web/API/StorageManager ، كما توضح معاملة IndexedDB: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction . لا تمثل هذه الوثائق ضمانًا بأن كل محرك وكل نظام ملفات يتصرفان بالطريقة نفسها عند فقد الطاقة. ولشرح أنواع التخزين والعزل بين البروفايلات اقرأ إيجي تاج: https://egytag.com/ar/articles/storage-apis-hossam-wagdy-2026-10-03 . أما هذا الدليل فيختبر سلامة المعاملات عند الفشل وحدود الحصة والتحديث، لا مجرد فصل الكوكيز بين الحسابات.
شارك في تقييم ونقاش المقال
رأيك يضيف قيمة للمقال ويساعدنا على تحسين المحتوى والنقاش حوله.
النقاش
جارٍ تحميل التعليقات…