English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

ملخص تقنيات Ajax و Comet

Ajax هو تقنية، تقنية تمكن من طلب بيانات إضافية من الخادم دون إزالة الصفحة، مما يمكن للصفحة من الحصول على تجربة مستخدم أفضل. يتمثل جوهر تقنية Ajax في ميزة XMLHttpRequest (XHR). يبدأ هذا المقال من XHR، لفهم خصائص تقنية Ajax، ثم تقديم فهم بسيط وتلخيص لتقنيات مثل CORS وComet.

استخدام XMLHttpRequest الأساسي

يحتوي XHR على طريقتين شائعتين هما open و send. تستخدم الطريقة open لبدء HTTP request، ولكن لن يرسل HTTP request فعليًا. تأخذ طريقة open ثلاثة معلمات، تشير كل منها إلى طريقة HTTP المطلوبة، URL الطلب، والنوع الإضافي. تستخدم الطريقة send لارسال request التي تم بدءها بواسطة open. تأخذ طريقة send معلمات واحدة، تشير إلى بيانات جسم HTTP request. إذا كان request هو GET، فهذا هو request بدون بيانات جسم، يكفي إدخال null. إذا كان request هو POST، يُدخل البيانات التي يجب POSTها. إليك مثال بسيط، لإرسال request GET إلى /api/data وبهذه الطريقة يتم إرسال request بشكل غير متزامن، أي أن هذا request لن يوقف تنفيذ code JS الأخرى في الصفحة.

var xhr = new XMLHttpRequest();
xhr.open("get", "/api/data", true)
xhr.send(null)

سيتم تلقائيًا ملء البيانات المستجابة التي يتم الحصول عليها في خصائص XHR، وتحتوي هذه الخصائص على أربعة خصائص رئيسية كالتالي:

* responseText: نص الجسم الاستجابة
* responseXML: إذا كان نوع محتوى الاستجابة "text/xml" أو "application/xml"، سيحتوي هذا الخاصية على وثيقة DOM XML لبيانات الاستجابة
* status: رمز حالة الاستجابة HTTP، عادة يمكن اعتبار رمز HTTP 200 كعلامة على النجاح
* statusText: شرح حالة HTTP

ميزة XHR يحتوي على خاصية readyState تسجل الحالة التي قد يمر بها هذا الميزة من إنشائه إلى استلام بيانات الاستجابة، وتحتوي حالة readyState على خمس حالات محتملة كالتالي:

0: لم يتم استدعاء طريقة open() لتشغيل الطلب بعد

1: تم استدعاء طريقة open() ولكن لم يتم استدعاء طريقة send() بعد

2: تم استدعاء طريقة send() ولكن لم يتم استقبال الرد بعد

3: تم استقبال جزء من بيانات الرد، ولكن لا تزال هناك بيانات لم يتم استقبالها

4: تم استقبال جميع بيانات الرد، أي أن الرد انتهى وبالبيانات كاملة

يتم إطلاق حدث readystatechange عندما يتغير state من قيمة إلى أخرى، وعند إطلاق هذا الحدث، يجب التحقق في معالج الحدث من قيمة state لمعرفة ما إذا كانت 4، وعندما تكون القيمة 4 يمكن معالجة البيانات الردية بشكل تالي. يجب تحديد معالج حدث readystatechange قبل استدعاء open() لضمان التكامل عبر المتصفحات. إليك مثال بسيط.

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.status, xhr.responseText)
 {}
{}
xhr.open("get", "/api/data", true)
xhr.send(null)

يقدم XHR كائن طريقة setRequestHeader() لضبط معلومات رأس HTTP المخصصة للطلب، ويقبل هذه الطريقة اثنين من المعلمات، وهو الحقل الذي يتم ضبطه والقيمة المطلوبة. يجب استدعاء setRequestHeader() بعد استدعاء open() لبدء الطلب ولكن قبل استدعاء send() لضمان النجاح. بعد تلقي الرد، يمكن الحصول على معلومات رأس HTTP للرد من خلال طريقة getResponseHeader()، ويقبل هذه الطريقة معلمتين، وهو اسم الحقل الذي يتم الحصول عليه. يمكن الحصول على جميع معلومات الرؤوس من خلال طريقة getAllResponseHeaders(). إليك مثال بسيط.

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.status, xhr.responseText)
  console.log(xhr.getResponseHeader('SomeKey'))
  console.log(xhr.getAllResponseHeaders())
 {}
{}
xhr.open("get", "/api/data", true)
xhr.setRequestHeader("SomeKey", "SomeValue")
xhr.send(null)

FormData

تعريف XMLHttpRequest 2 مستوى نوع FormData كنوع سلسلة بيانات استمارة، لإنشاء بيانات بنفس صيغة الاستمارة، لتسهيل نقل البيانات عبر XHR. يوفر FormData طريقة append() لاضافة بيانات مباشرة، ويقبل هذه الطريقة اثنين من المعلمات، وهي المفتاح والقيمة. يمكن ترك تعريفه فارغًا أو يمكنه استقبال عنصر استمارة مباشرة. بعد استقبال العنصر الاستمارة، سيتم استخدام بيانات هذا العنصر لملء مجموعة المفاتيح القيم في عنصر FormData مسبقًا. إليك مثال بسيط.

var form = document.getElementById('myForm');
var data = new FormData(form);
data.append('someKey', 'someValue');
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.responseText)
 {}
{}
xhr.open('post', '/api/upload', true)
xhr.send(data)

مشاركة الموارد عبر الحدود

قد تواجه الاتصال ببروتوكول AJAX عبر XHR قيوداً، وهي قيود الأمان عبر الحدود. تقيد سياسة الأمان عبر الحدود بـ “نفس النطاق، نفس الميناء، نفس البروتوكول”, عندما يحاول XHR الوصول إلى موارد خارج القيود سيتم إطلاق خطأ أمني. CORS (Cross-Origin Resource Sharing)، مشاركة الموارد عبر الحدود، تعتمد على استخدام رؤوس HTTP مخصصة للاتصال بين المتصفح والخادم لتحديد نجاح أو فشل الطلبات أو الإجابات، ويجب أن يدعم المتصفح والخادم كلاهما لتحقيق الوصول العادي. في الوقت الحالي، يدعم معظم المتصفحات CORS، لذا يمكن كتابة الكود بنفس الطريقة التي يتم بها الوصول إلى الموارد في نفس النطاق، فقط يجب استخدام مسار مطلق للURL. لذا، فإن المفتاح لتحقيق الوصول عبر الحدود يكمن في الخادم، ولا يتم مناقشة كيفية تحقيق ذلك في هذا المقال. إليك مثال بسيط في JavaScript الأمامي.

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
 if (xhr.readyState === 4) {
  console.log(xhr.responseText)
 {}
{}
xhr.open('get', 'http://www.otherserver.com/api/data', true)
xhr.send(null)

JSONP

JSONP (JSON مع التعويض) هو طريقة لتحقيق الوصول إلى موارد عبر الحدود باستخدام JSON. يتكون JSONP من جزأين: دالة التلقي والبيانات JSON. كما ذكرنا من قبل، قد تواجه طلبات XHR قيوداً أمنية عبر الحدود، ولكن لا يوجد قيود على علامة script في HTML، يمكننا استخدام علامة script لاستدعاء ملفات JS من أماكن مختلفة. يتم استغلال هذا الفراغ من قبل JSONP، حيث يتم إنشاء عنصر script ديناميكي، ثم إشراك src إلى عنوان URL آخر من مجال آخر لتحقيق تحميل موارد مجال آخر، ثم معالجة البيانات المحملة من خلال دالة التلقي. إليك مثال بسيط.

function handler(res) {
 console.log(res)
{}
var script = document.createElement('script')
script.src = 'http://www.otherserver.com/api/data/?callback=handler'
document.body.insertBefore(script, document.body.firstChild)

يحدد هذا الكود إنشاء عنصر script الديناميكي src له عنوان دومين آخر هو /api/data، ويحدد أيضًا دالة التصفية كـ handler. بعد إدراج عنصر script في DOM، يتم تحميل البيانات من URL المحدد، ثم يتم تحليل البيانات JSON المكتسبة إلى عنصر معين وتطبيق handler لمعالجتها.

JSONP هو طريقة بسيطة لتحقيق الوصول عبر الحدود، ولكنه يحتوي أيضًا على بعض المخاطر الأمنية، مثل أن يستجيب URL الأخرى التي تطلبها بكتلة برمجية ضارة. هناك أيضًا مشكلة أخرى في JSONP، حيث يتم تضمين tag script الذي يحتوي على js، والذي يدعم json، لذا يجب التأكد من أن URL الأخرى التي يتم طلبها يستجيب بشكل صحيح بصيغة json، وليس XML.

Comet

Ajax هو تقنية لطلب البيانات من الخادم من خلال الصفحة، بينما Comet يختلف عنه، حيث هو تقنية لإرسال البيانات من الخادم إلى الصفحة، ويدعم التطبيقات التي تتطلب سرعة تفاعلية عالية. هناك طريقتان لتحقيق Comet: طلب الاستقصاء الطويل واتصال التدفق. قبل الحديث عن طلب الاستقصاء الطويل، دعنا نتحدث عن طلب الاستقصاء القصير، والذي يتميز برسالة بسيطة، حيث يستخدم العميل جهاز تقويم، وكل فترة زمنية معينة يرسل طلب Ajax إلى الخادم للاستفسار عن تحديث البيانات، ويكون هذا الوقت الزمني صغيرًا غالبًا. طلب الاستقصاء الطويل مشابه لذلك، حيث يستمر العميل في إرسال طلبات إلى الخادم، ولكن الفرق هو أن العميل لا يحتاج إلى إرسال طلبات بانتظام بناءً على فترات زمنية معينة، بل يرسل طلبًا واحدًا إلى الخادم، ويبقى اتصال HTTP بين العميل والخادم مفتوحًا حتى يتحقق الخادم من وجود تحديثات للبيانات، ثم يستجيب من خلال هذا الاتصال ببيانات العميل، ويغلق اتصال HTTP مرة أخرى. بعد ذلك، يبدأ المتصفح في إرسال اتصال جديد لإكمال العملية مرة أخرى. بالمقارنة مع طلب الاستقصاء القصير، يتم فتح عدد أقل من اتصالات HTTP في طلب الاستقصاء الطويل، ولكن إذا بقي اتصال HTTP مفتوحًا لفترة طويلة، فإنه يستخدم موارد الخادم أيضًا.

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

SSE

SSE (Server-Send Events)، أحد تحسينات الاتصال بين الخادم والعميل، هو API يقدم من قبل المتصفح لدعم التفاعل باتجاه واحد، يدعم كلاً من التحقق الدوري والتهديد بالبث المباشر. يتم استخدام API SSE لإنشاء اتصال أحادي التدفق إلى الخادم، يمكن للخادم من خلال هذا الاتصال إرسال أي عدد من البيانات إلى العميل. يتم إرسال رد الخادم بنوع MIME text/event-stream. إليك مثال بسيط لـ API JavaScript لـ SSE.

var source = new EventSource("/api/events")
source.onmessage = function(event) {
 console.log(event.data)
{}

كما هو موضح في الكود المقدم، لتحديد تدفق الحدث على الخادم للحصول على البيانات التي يرسلها الخادم، يجب أولاً إنشاء كائن EventSource، ثم معالجة الحدث عند تفعيل حدث message. يتم حفظ البيانات التي يرسلها الخادم على شكل نص في event.data. سيحافظ كائن EventSource على الاتصال النشط مع الخادم، وسيتم إعادة الاتصال في حالة قطع الاتصال، وإذا كنت ترغب في قطع الاتصال بشكل دائم يمكنك تحقيق ذلك عن طريق دعوة طريقة close(). سيتم تفعيل حدث message لـ EventSource عند استقبال حدث جديد من الخادم، بالإضافة إلى حدث message، هناك حدثان آخران هما open وerror، حيث يتم تفعيل حدث open عند إنشاء الاتصال، وحدث error عند عدم القدرة على إنشاء الاتصال.

Web Sockets

Web Sockets هي قناة تواصل مزدوج المزدوج مع الخادم. لا يستخدم Web Sockets بروتوكول HTTP، بينما تستخدم Ajax وComet بروتوكول HTTP. نظرًا للقيود في النطاق، لن يتم مناقشة Web Sockets في هذا المقال.

الخلاصة

Ajax يتيح الحصول على بيانات من الخادم دون تحميل الصفحة، مما يزيد من تجربة المستخدم على الصفحة. قد تواجه تقنية XHR الخاصة بـ Ajax قيود استراتيجيات الأمان عبر الحدود، ولتجنب مشكلة الحدود عبر CORS، يتطلب ذلك التعاون بين الجانبين المتعلقين بالخادم والbrowser. JSONP هي "نقطة ضعف" صغيرة لتحقيق الوصول عبر الحدود، ولكن هناك بعض المشاكل. Comet يوسع Ajax، مما يسمح للخادم ببث البيانات في الوقت الحقيقي إلى browser، ولكن من الناحية التنفيذية، سواء كان التحقق دوريًا أو تدفق HTTP، يبدأ browser في إرسال طلب إلى الخادم أولاً. يملك Web Sockets خاصية التواصل المزدوج المزدوج، ويمكنك معرفة المزيد عنها في وقت لاحق.

هذا هو محتوى المقال كله، نأمل أن تساعد محتويات هذا المقال في تعلم أو عمل الجميع بشكل ما، ونأمل أيضًا أن تدعم تعليمات الصياح بشكل أكبر!

البيان: محتويات هذا المقال تم جمعها من الإنترنت، ملكية المحتويات لصاحب الحقوق، محتويات المشاركة تم جمعها من قبل المستخدمين عبر الإنترنت وتم تحميلها بشكل مستقل، هذا الموقع لا يمتلك حقوق الملكية، لم يتم تعديل المحتويات بشكل يدوي، ولا يتحمل هذا الموقع أي مسؤولية قانونية. إذا كنت قد وجدت محتويات تتضمن حقوق النسخ، فنرجو منك إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (عند إرسال البريد الإلكتروني، يرجى استبدال '#' بـ '@') لتقديم الشكوى، وتقديم الدليل ذات الصلة، وسيتم حذف المحتويات المشبوهة التي تم اكتشافها على الفور.

سيذهب لك