شرح عملي لبناء إضافة Chrome وتمرير الرسائل من سياق الصفحة إلى الإضافة
مقدمة: لماذا نحتاج إلى تمرير الرسائل في إضافات Chrome؟
تُعد إضافات Chrome من الأدوات الفعّالة التي تمنح المتصفح قدرات إضافية تتجاوز ما توفره الصفحة بشكل افتراضي. يمكن استخدامها لتحليل عناصر DOM، أو تعديل الطلبات، أو عرض بيانات مهمة للمستخدم داخل واجهة منفصلة وسهلة الاستخدام.
لكن عند تطوير إضافة متقدمة، ستواجه مشكلة شائعة: بعض البيانات أو الدوال الموجودة داخل سياق الصفحة نفسها لا يمكن الوصول إليها مباشرة من content script. وهنا يظهر مفهوم تمرير الرسائل بين مكونات الإضافة كحل أساسي وعملي.
في هذا الدليل، سنشرح بطريقة مبسطة كيف يمكن تمرير البيانات من سياق الصفحة إلى الإضافة، مع توضيح دور كل جزء من الأجزاء التالية:
Popup ScriptBackground ScriptContent ScriptInjected Script

فهم بنية إضافة Chrome وآلية التواصل بين السكربتات
تعمل إضافة Chrome كطبقة إضافية فوق صفحة الويب. ورغم أن جميع الأجزاء تبدو مترابطة، فإن لكل جزء بيئة تنفيذ وصلاحيات مختلفة. لذلك لا يمكن لأي سكربت الوصول إلى كل شيء بشكل مباشر.
المكونات الأساسية داخل الإضافة
Popup Script: المسؤول عن منطق الواجهة التي تظهر عند الضغط على أيقونة الإضافة.Background Script: يحتفظ بالحالة العامة للإضافة ويتعامل مع الأحداث المستمرة.Content Script: يعمل داخل الصفحة ويستطيع التعامل معDOM، لكنه لا يصل مباشرة إلى متغيرات الصفحة المحلية.Injected Script: يتم حقنه داخل الصفحة نفسها، وبالتالي يمكنه الوصول إلى الكائنات والمتغيرات الموجودة في سياق الصفحة.
إذا كان هدفك مجرد قراءة عناصر HTML من الصفحة، فغالباً يكفي الاعتماد على content script. أما إذا احتجت إلى الوصول إلى خصائص ضمن الكائن window أو استدعاء دوال موجودة في الصفحة، فلا بد من استخدام سكربت محقون ثم تمرير البيانات تدريجياً عبر بقية مكونات الإضافة.

كيف تعمل عملية تمرير الرسائل خطوة بخطوة؟
الفكرة الأساسية كالتالي:
- يتم حقن سكربت مخصص داخل الصفحة.
- يصل هذا السكربت إلى البيانات أو الدوال الموجودة في سياق الصفحة.
- يرسل البيانات إلى
content scriptباستخدامwindow.postMessage. - يقوم
content scriptبإرسال هذه البيانات إلىbackground scriptعبر واجهاتChrome Runtime API. - تقوم واجهة الإضافة في
popupبقراءة البيانات من الخلفية وعرضها للمستخدم.
هذا الأسلوب مفيد جداً عندما تريد بناء إضافة تعرض معلومات ديناميكية مثل بيانات الأداء أو حالة التطبيق أو القيم المخزنة داخل الصفحة.
مثال تطبيقي: بناء إضافة لمراقبة بيانات performance
سنفترض هنا أننا نريد إنشاء إضافة بسيطة تقوم بقراءة بيانات الأداء من الكائن العام window ثم تعرض أهم المؤشرات داخل نافذة الإضافة. هذا المثال ممتاز لفهم انتقال البيانات بين السياقات المختلفة.
ملف manifest.json: نقطة البداية لأي إضافة
كل إضافة في Chrome تحتاج إلى ملف manifest. هذا الملف يحدد بيانات الإضافة، وصلاحياتها، والسكربتات التي ستعمل ضمنها.

أهم الخصائص التي يجب فهمها:
background: يحدد السكربتات التي تعمل في الخلفية.content_scripts: يضم السكربتات التي يتم تشغيلها داخل الصفحات المستهدفة.web_accessible_resources: يحدد الملفات التي يمكن للصفحة الوصول إليها، مثل سكربتات الحقن أو الصور.permissions: يمنح الإضافة الصلاحيات اللازمة للوصول إلى واجهات مثلtabs.
من المهم الانتباه إلى أن هذا الشرح يعتمد على Manifest V2. في Manifest V3 توجد اختلافات مهمة، أبرزها الاعتماد على service workers بدلاً من صفحات الخلفية التقليدية.
دور Content Script في حقن السكربت والتقاط الرسائل
يمتلك content script وصولاً مباشراً إلى بنية الصفحة، لذلك نستخدمه لإضافة السكربت المخصص داخل DOM.

وظيفته لا تتوقف عند الحقن فقط، بل يواصل أيضاً الاستماع إلى الرسائل القادمة من السكربت المحقون. وبمجرد استلام البيانات، يمكنه التحقق منها والتأكد من أن الإضافة تعمل كما هو متوقع، ثم إعادة إرسالها إلى الخلفية باستخدام chrome.runtime.sendMessage.

لماذا لا يكفي Content Script وحده؟
لأن content script يعمل في بيئة معزولة نسبياً. هو يرى DOM، لكنه لا يستطيع الوصول المباشر إلى المتغيرات والدوال التي أنشأتها الصفحة في سياقها الخاص. لهذا السبب نلجأ إلى حقن سكربت فعلي داخل الصفحة.
السكربت المحقون Injected Script: الجسر الحقيقي إلى متغيرات الصفحة
بمجرد حقن السكربت داخل الصفحة، يتعامل المتصفح معه كما لو أنه جزء من الصفحة نفسها. وهذا يعني أنه يستطيع الوصول إلى الكائن window والبيانات المخزنة داخله.

في هذه المرحلة، من الأفضل استخراج الخصائص الضرورية فقط بدلاً من تمرير كائنات ضخمة لا حاجة لها. هذا يحسن الأداء ويقلل من التعقيد.
بعد جمع البيانات، يتم تمريرها بأمان إلى content script باستخدام الدالة window.postMessage. ويمكن استخدام setInterval() إذا كانت القيم تتغير باستمرار وتحتاج إلى تحديث دوري.

مثال مبسط على منطق السكربت المحقون
setInterval(() => {
const perfData = {
timing: window.performance.timing,
navigation: window.performance.navigation
};
window.postMessage({
source: 'my-extension',
payload: perfData
}, '*');
}, 1000);
هذا المثال يوضح الفكرة العامة: قراءة البيانات من window.performance ثم إرسالها بشكل دوري.
السكربت الخلفي Background Script: تخزين البيانات وربطها بعلامات التبويب
يقوم background script بالاستماع إلى الرسائل القادمة من content script. بعد ذلك يمكنه تخزين البيانات بطريقة تجعل الوصول إليها ممكناً من نافذة الإضافة.

من الأساليب الشائعة هنا استخدام tab.id كمفتاح لتمييز بيانات كل تبويب على حدة. بهذه الطريقة، إذا كان المستخدم يتنقل بين عدة صفحات، تستطيع الإضافة عرض المعلومات الصحيحة لكل تبويب نشط.
فوائد تخزين البيانات في الخلفية
- الحفاظ على حالة الإضافة أثناء تنقل المستخدم.
- فصل منطق جمع البيانات عن منطق العرض.
- تسهيل الوصول إلى البيانات من واجهات مختلفة داخل الإضافة.
واجهة Popup: عرض البيانات للمستخدم بطريقة مفهومة
في نافذة الإضافة، يتم أخيراً جلب البيانات التي وصلت من الصفحة. يعتمد ذلك غالباً على الدالة getBackgroundPage() في بنية Manifest V2، ثم تحديد التبويب الحالي باستخدام tabs.query() لاستخراج البيانات المرتبطة به.

هنا يمكنك تحويل البيانات الخام إلى عناصر مرئية مفهومة، مثل:
- وقت تحميل الصفحة.
- مدة الاستجابة الأولية.
- مؤشرات التنقل والأداء.
- أي مقاييس مخصصة يحتاج إليها المستخدم.
نصائح عملية لتحسين بنية تمرير الرسائل داخل إضافات Chrome
1. أرسل أقل قدر ممكن من البيانات
بدلاً من تمرير الكائن window بالكامل أو بيانات ضخمة، استخرج فقط القيم المطلوبة. هذا يجعل الإضافة أسرع وأكثر استقراراً.
2. استخدم معرفاً واضحاً للرسائل
من الأفضل أن تحتوي كل رسالة على حقل مثل source أو type حتى تستطيع تمييز الرسائل الخاصة بإضافتك عن غيرها.
3. تحقّق من صحة البيانات قبل معالجتها
لا تفترض أن كل رسالة مستلمة سليمة. أضف شروط تحقق لحماية الإضافة من الأخطاء أو القيم غير المتوقعة.
4. راعِ الفروق بين Manifest V2 وManifest V3
إذا كنت تبني مشروعاً جديداً، فمن المهم دراسة الفروقات المعمارية جيداً، لأن طريقة إدارة الخلفية اختلفت بشكل واضح في الإصدارات الأحدث.
متى تحتاج هذا الأسلوب فعلاً؟
يصبح هذا النمط ضرورياً في الحالات التالية:
- عند الحاجة للوصول إلى متغيرات الصفحة غير الظاهرة في
DOM. - عند قراءة بيانات من كائنات عامة مثل
window.__INITIAL_STATE__. - عند تحليل أداء الصفحة من خلال
window.performance. - عند التعامل مع تطبيقات الويب الحديثة التي تعتمد على بيانات ديناميكية داخل الذاكرة.
ملخص تدفّق البيانات داخل الإضافة
| المرحلة | المكون | الدور |
|---|---|---|
| 1 | Injected Script |
الوصول إلى متغيرات ودوال الصفحة |
| 2 | window.postMessage |
إرسال البيانات من سياق الصفحة |
| 3 | Content Script |
استقبال الرسائل وتمريرها إلى الإضافة |
| 4 | Background Script |
تخزين البيانات وربطها بالتبويب الحالي |
| 5 | Popup Script |
قراءة البيانات وعرضها للمستخدم |
الخلاصة التقنية
فهم آلية تمرير الرسائل في إضافات Chrome ليس مجرد تفصيل تقني، بل هو أساس بناء إضافات احترافية تتعامل مع بيانات الصفحة بمرونة وأمان. عندما تفصل بين مهام الوصول إلى البيانات، ونقلها، وتخزينها، وعرضها، ستحصل على بنية أوضح وأسهل في التطوير والصيانة. وإذا كنت تعمل على إضافة تحتاج إلى قراءة متغيرات داخلية من الصفحة، فإن الجمع بين Injected Script وContent Script وBackground Script يظل واحداً من أكثر الحلول فعالية واعتمادية.