طرق مزامنة علامات تبويب المتصفح



منذ وقت طويل ، في مجرة ​​بعيدة ، ظهرت مهمة لمزامنة علامات تبويب المتصفح لمشغل الويب ، مثل VK: كان من الضروري تنظيم تبادل البيانات بين علامات التبويب وتتبع عددها وتعيين المهام لبعضها. يجب أن يتم التنفيذ بالكامل على العميل. تم جمع الكثير من المعلومات وكتابتها في مقال كامل.

أدناه سوف أصف طرق مختلفة لحل مثل هذه المشاكل.

فكر في الطرق الأكثر شيوعًا لمزامنة علامات تبويب المتصفح من أجل زيادة التعقيد.

التخزين المحلي


localStorage - التخزين المحلي ، خاصية لكائن النافذة ، يسمح لك بالوصول إلى كائن التخزين المحلي. يمكنه تخزين البيانات بين جلسات المستخدم. هناك خاصية مماثلة - جلسة التخزين ، لكنها تخزن البيانات فقط لمدة جلسة الصفحة.
تتم إضافة البيانات إلى التخزين باستخدام طريقة setItem .

localStorage.setItem('key', 'value'); 

يعتبر حدث التخزين مثاليًا لمزامنة البيانات بين علامات التبويب ؛ ويتم إنشاؤه عندما تتغير قيمة عنصر التخزين المحلي أو عنصر التخزين.

 window.addEventListener('storage', function(event) { console.log(event.key); }); 

لا يعمل هذا الحدث على علامة التبويب ، مما يُجري تغييرات ، ولكنه يُشعل في علامات التبويب المتبقية للنطاق في المتصفح.

توليد حدث التخزين

لدى المستعرضات مستويات تخزين مختلفة للتخزين المحلي وجلسة التخزين:

  • Chrome و FireFox و Opera ~ 5 ميغابايت.
  • IE ~ 4.8 ميغابايت.
  • iOS Safari و OS X Safari ~ 2.5 ميغابايت.
  • Android ~ 5 ميغابايت.

من بين أوجه القصور ، يمكن للمرء أن يلاحظ حجم تخزين المتصفح ، وعندما يكون ممتلئًا ، فلن يتم تسجيل كائن جديد.
تعمل هذه الطريقة في جميع المتصفحات باستثناء Opera mini .

نشر رسالة


postMessage هي طريقة تسمح لك بإرسال الطلبات عبر النطاقات بشكل آمن ، أي التواصل مع بعضها البعض إلى النوافذ وإطارات iframe من مجالات مختلفة.
إنه ملائم للغاية لتفاعل الحاجيات والخدمات الخارجية المتصلة عبر iframe من الصفحة الرئيسية.
إرسال الرسالة:

 const win = window.frames.target; win.postMessage('send message', 'http://javascript.ru'); 

يمكن أن تكون البيانات المرسلة أي كائن يدعم الاستنساخ (سلسلة ، كائن ، صفيف ، خريطة ، تاريخ ...). لكن IE يدعم فقط السلاسل.

يشير عنوان Url إلى أنه يمكن فقط للنوافذ من هذا المصدر تلقي الرسائل.
لتلقي الرسائل ، يجب أن تشترك النافذة في حدث onmessage.

 window.addEventListener('message', function(event) { if (event.origin != 'http://javascript.ru') { return; } console.log(event.data); }); 

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

في IE ، تعمل واجهة postMessage فقط مع إطارات iframe ولا تعمل بين علامات التبويب والنوافذ.

بث قناة API


يوفر Broadcast Channel API رابطًا بسيطًا بين سياق العرض (النوافذ وعلامات التبويب). ينشئ كائن BroadcastChannel قناة مشتركة تسمح لك بتلقي أي رسالة مرسلة إليه. يمكن لعلامات التبويب والنوافذ وإطارات iframes الاشتراك في القناة وإنشاء اتصال معها.

 const bc = new BroadcastChannel('test_channel'); 

ينشر أسلوب postMessage رسالة إلى القناة. الحجة هي نوع يدعم الاستنساخ .

 bc.postMessage('This is a test message.'); 

عندما يتم نشر رسالة ، سيتم إرسال حدث رسالة إلى كل كائن متصل بهذه القناة.

 bc.addEventListener('message', function (e) { console.log(e); }) 


نشر رسالة على قناة لسياقات مختلفة.

واجهة برمجة التطبيقات بسيطة جدًا ؛ يمكن اعتبارها ناقل رسائل بسيط. لكن الطريقة لها عيب خطير: لا يوجد دعم لـ Safari و IE .

للوهلة الأولى ، يمكنك العثور على العديد من الطرق المماثلة لنقل البيانات (على سبيل المثال MessageChannel و WebSocket) ، ولكن كل منها يخدم غرضًا محددًا - المقارنة .

عمال الويب


هذه آلية تسمح بتشغيل نص برمجي في سلسلة رسائل خلفية منفصلة عن سلسلة الرسائل الرئيسية لتطبيق ويب. يتم تنفيذه باستخدام ملفات js ، التي يتم تضمينها في الصفحة باستخدام طلب HTTP غير متزامن.

العمال رائعون لأداء عمليات الحوسبة الثقيلة دون إبطاء واجهة المستخدم.
ولكن مع المزامنة ، يمكن أن يساعد نوعان فقط من العمال.

عامل مشترك


هذا نوع خاص من العمال يمكن الوصول إليه من سياقات متصفح عديدة. لنكتب ملف js مشتركًا لعلامات التبويب ، على سبيل المثال Shared-worker.js.

 const worker = new SharedWorker('shared-worker.js'); 

يمكن لكل علامة تبويب التواصل مع العامل من خلال عامل worker. البرنامج النصي للعامل لديه حق الوصول إلى منافذه. في كل مرة تتصل علامة التبويب بالعامل ، يتم تشغيل حدث الاتصال في البرنامج النصي.

 // shared-worker.js const connections = []; onconnect = function(e) { const port = e.ports[0]; connections.push(port); }; 

تم إنشاء طريقة postMessage لإرسال بيانات علامة التبويب إلى عامل مشترك.

 worker.port.postMessage('test message'); 

يمكنك استرداد بيانات العامل باستخدام حدث الرسالة.

 worker.port.onmessage = function (e) { console.log(e.data); }; 

يوجد حدث اتصال في SharedWorker API ، ولكن لا يوجد حدث قطع ، وبالتالي لن تتمكن البيانات من التنظيف الذاتي في علامات التبويب المغلقة - سيستمر اعتبارها مفتوحة. لن يؤدي ذلك إلى حدوث أخطاء ، ولكن يمكن اعتباره عيبًا أو ميزة API.

يعمل فقط في Chrome و FF .

عامل الخدمة


هذا عامل مدفوع بالحدث يمكنه مراقبة طلبات الشبكة واعتراضها وتعديلها وتخزينها مؤقتًا.
تسجيل العمال:

 if ('serviceWorker' in navigator) { navigator.serviceWorker.register('service-worker.js') .then(function() { return navigator.serviceWorker.ready; }) .catch(function(error) { console.error('registration error : ', error); }); } 

باستخدام حدث الرسالة ، يمكن لعلامات التبويب استلام البيانات من ملف js worker ، ويتم استخدام وظيفة syncTabState لمعالجة الرسالة.

 self.addEventListener('message', function(e){ const data = e.data; const tabId = e.source.id self.syncTabState(data, tabId); }); 

تم تصميم وظيفة sendTabState لإرسال رسائل إلى علامات التبويب.

 self.sendTabState = function(client, data){ client.postMessage(data); } 

استخدام مفصل والعديد من الأمثلة هنا .

لا يستطيع جميع عمال الويب الوصول إلى النافذة وكائنات المستند.

عامل الخدمة لا يعمل في IE و Opera mini .

مكتبات التزامن


هذه طريقة لأولئك الذين لا يريدون ركوب الدراجة وهم على استعداد للنظر في الحلول الحالية.


عيبها هو أن المكتبات عالمية في الغالب ، لذلك فهي ليست مناسبة دائمًا للحلول الضيقة.

الملخص


للتلخيص ، دعنا نقارن بين طرق دعم المتصفح بشكل مرئي.


استخدم LocalStorage و BroadcastChannel و PostMessage للحالات البسيطة عندما تحتاج إلى إرسال رسالة إلى العديد من النوافذ / علامات التبويب أو إطارات iframe.

يعتبر العمال المشتركون وعامل الخدمة أنسب الحلول لإدارة أقفال الحالة المشتركة والملفات المشتركة.

وبالنسبة للمهمة مع مشغل الويب ، تم تحديد LocalStorage ، حيث يوجد دعم لـ IE.
آمل أن تكون هذه المقالة قد ساعدتك في اختيار طريقة المزامنة الصحيحة.

أشكر فريق الملصقات على مساعدتهم ودعمهم!

المقالات المستعملة:

Source: https://habr.com/ru/post/ar422545/


All Articles