الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

دليل مبسّط في Ajax

بدأه Xacker في 31 مارس 2008 · 6 رد · 1,417 مشاهدة · في منتدى تصميم صفحات الويب
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

اهتماماتي عشوائية, لكنها في النهاية تخدم هدفاً ما إما حالي وإما لاحق, فغالباً ما كنت اقرأ في تقنيات معينة لفترة طويلة تشد انتباهي ثم أتركها لشئ آخر كانت تعود لي وكنت أحتاجها فأجد ما تعلمته في فترة لاحقة جداً مفيد بالنسبة لي.. وهذا ما يحدث الآن فمن فترة كنت قد أضطررت للبحث في AJAX بشكل لا بأس فيه عندما كنت اكتب شفرة تقوم بالتلاعب بموقع (بشكل آمن و ethical :P ) فكانت AJAX هي ما افادني ولم تكن javascript كافيه..

فيما يلي سأقوم بتلخيص بعض أهم الأفكار التي من الممكن من خلالها (وآمل هذا) الاستفادة من هذه التقنيه عسى من الله تعالى ان اوفق بالشرح.

مقدمة إلى AJAX:

تتمتع تقنية اجاكس بمرونتها في العمل, فتفيد في عملية الحصول على المعطيات دون الحاجة الى تحديث الصفحة وكي لا تذهب بعيداً احد الامثلة على استخدامها هو الصفحة الرئيسية لموقع الفريق العربي للبرمجة, فهي مصممة بتقنية اجاكس, لاحظ كيف يمكن ان تقوم بفتح واغلاق المواضيع للمقالات الموجودة فيها دون الحاجة الى تحديث الصفحة, مع العلم انه لا يتم استخدام IFRAME او ما شابه.

تقوم اجاكس بالتعاون مع التقنيات التالية بتقديم قدرة هائلة على معالجة البيانات بشكل رائع:

- XHTML و CSS تقدم طريقة عرض قياسية.

- DOM تقدم طريقة تفاعلية في عرض النتائج.

- XML و XSLT تقدم طريقة لتبادل البيانات ومعالجتها.

- XMLHttpRequest يقدم طريقة او وظيفة لاتزامنية لاستعادة البيانات.

- JavaScript تقوم بجمع جميع هذه التقنيات سوية.

تعتمد بنية اجاكس على الكائن XMLHttpRequest بشكل أساسي والذي تم اعتماده من قبل متصفح IE 5.0 ومن ثم من قبل المتصفحات المتوافقة مع Mozilla.

XMLHttpRequest:

نستطيع من خلال هذا الكائن ان نقوم بارسال طلب الى السيرفر ومعالجة الرد من دون ان نقوم بمقاطعة المستخدم عن عمله. من الامثلة على هذا كما ذكرنا, الصفحة الرئيسية لموقع الفريق العربي للبرمجة, من الامثلة الاخرى العالمية, Gmail خدمة البريد من Google العملاقة, حيث من الممكن ملاحظة كيف بالامكان ان تقوم بتنفيذ عدة عمليات في الوقت نفسه مثل حذف بريدك الغير مهم والاطلاع على قائمة الاشخاص الموجودين حاليا على Gtalk و الامثلة عديدة, من الخدمات الاخرى, Google's Suggest خدمة اخرى من Google تمكنك من البحث عن كلمة ما وبنفس الوقت Google يقوم بعرض قائمة من الاحتمالات الخاصة بالبحث (شئ شبيه بالاكمال التلقائي), خدمة Map Quest .. والامثلة عديدة.

لنفرض الان اننا نريد قراءة محتويات ملف XML موجود على السيرفر يحوي بداخله على روابط لعناوين الاخبار الرئيسية للموقع الذي نقوم بتعديله فقط كي تتغير جميع العناوين في جميع الصفحات اضف الى هذا اننا نريد من الزائر ان يرى جميع الاخبار المحدّثة حتى لو لم يقم بتحديث او اغلاق واعادة فتح المتصفح مرة اخرى.

تهيئة وارسال الطلب Initializing and sending request:

الصفحة التي نتكلم عنها ستقوم بجلب عناوين وروابط الأخبار من ملف XML على السيرفر باسم headlines.xml, سيتم عرض النتائج عند اكتمال تحميل الصفحة بالكامل بالتالي عند تنفيذ حدث onload للصفحة:

<body onload="view()">

من خلال هذا الشكل فانه حالما يتم اكتمال تحميل الصفحة سيتم تنفيذ الوظيفة view()

لننظر الان الى وظيفة view() كي نفهم الامر بشكل أفضل:

var		 req; 
		   function view() {
					init(); 
					req.onreadystatechange = callBack; 
					req.send(null); 
		   }

الان لندخل في التفاصيل, فلدينا الوظيفة init() اختصارا لـ initialize اي اعداد او تهيئة

function init() {
								if (window.XMLHttpRequest) {
											req = new XMLHttpRequest();
								} else if (window.ActiveXObject) {
											req = new ActiveXObject("Microsoft.XMLHTTP");
								}
								var url = "./headlines.xml";
	  req.open("GET", url, true);
	  }

سأقوم بشرح الوظيفة الآن بالتدريج مع العلم انه عند هذه النقطة تسبب بطء الخط لدي في عطب بقية المقال بالكامل بعد ان كان شارف على الانتهاء واضطررت الى اعادة كتابته من جديد... يا ريت الدعاء يكون مضاعف :)

وظيفة init() في البداية تقوم بتهيئة الكائن XMLHttpRequest الذي تكلمنا عنه سابقا لكن بسبب اختلاف الاصدارات من المتصفحات واختلاف المتصفحات نفسها يجب علينا في البداية ان نحدد نوع الكائن الموافق للمتصفح المستخدم, لذلك نقوم بالاعتماد على عنصر window بطلب الكائن XMLHttpRequest, فحص المتصفح لمعرفة فيما اذا كان يدعم XMLHttpRequest بشكل مباشر يمكننا من تهيئة الكائن في حالة متصفحات مختلفة, ان لم يكن يدعم هذا الكائن باسمه الحالي فان بعض اصدارات المتصفح IE تدعمه من خلال ActiveX لذلك نقوم بتهيئته في حال فشل الفحص الأول.

Mozilla تدعم الكائن XMLHttpRequest

Microsoft تدعم الكائن باسم XMLHTTP

:P

ما رأيك بان حتى اصدارات IE المختلفة لها ارقام مختلفة لـ XMLHTTP :angry2:

						if (window.XMLHttpRequest) {
											req = new XMLHttpRequest();
								} else if (window.ActiveXObject) {
											req = new ActiveXObject("Microsoft.XMLHTTP");
								}

بسبب الاختلافات بين المتصفحات (تباً لهم) كنت اضطررت الى استخدام التالي:

function xmlhttp(){
	  var obj;
	  var xml = new Array();
	  xml[0] = "MSXML2.XMLHTTP.5.0";
	  xml[1] = "MSXML2.XMLHTTP.4.0";
	  xml[2] = "MSXML2.XMLHTTP.3.0";
	  xml[3] = "MSXML2.XMLHTTP";
	  xml[4] = "Microsoft.XMLHTTP";
	  xml[5] = "WinHttp.WinHttpRequest.5";
	  xml[6] = "WinHttp.WinHttpRequest.5.1";
	  if (window.ActiveXObject) {
		  for (var i=0; i<xml.length; i++){
		   try {
			obj = new ActiveXObject(xml);
			break;
		   } catch(e) {obj = null;}
		  }
	  } else if (window.XMLHttpRequest) {
		  try {
		   obj = new XMLHttpRequest();
		  } catch(e) {obj = null;}
	  }return obj;
	  }

هذا الكود شئ ثابت يمكن استخدامه بدون الرجوع اليه مرة أخرى, يمكنك دوما حفظه في ملف js وطلبه عند الحاجة :)

نأتي الى الجزء التالي الآن

var url = "./headlines.xml";
	  req.open("GET", url, true);

في البداية نقوم بتشكيل الرابط المطلوب جلب البيانات منه, طبعا يمكن الاستغناء عن هذا نستطيع فورا استخدامه لاحقا بشكل مباشر.

علينا الان ان نقوم بتحديد نوع الاتصال المطلوب انشاؤه, هل هو POST, GET, الخ من خلال طلب open (ما هي أفضل ترجمة لـ method كمصطلح علمي :nose_pick: )

في حالتنا هنا لن نقوم بارسال بيانات لذلك سنستخدم GET

طريقة استدعاء الطلب open يتم بالشكل التالي

open (method, URL, async)

method = POST / GET / PUT / DELETE / HEAD

URL = الرابط المراد استرجاع او ارسال البيانات منه/اليه

async = يحدد فيما اذا كانت العملية تزامنية او لا, وهو عبارة عن عنصر BOOLEAN

في حال امتلك القيمة TRUE فان السكربت يتابع عمله ضمن المتصفح بالتالي يسمح للمستخدم بإكمال او متابعة عمله في المتصفح بحرية دون الحاجة الى الانتظار الى انتهاء اكتمال استقبال البيانات او ارسالها.

في حال كانت القيمة FALSE فاننا نطلب من المتصفح ان ينتظر دون اكمال او السماح بالقيام باي اعمال اخرى حتى يتم الانتهاء من الطلب.

يفضل في معظم الحالات استخدام TRUE, لكن طبعا الامر يعود الى المبرمج والهدف من السكربت.

:stop: عندما يأخذ بارامتر async القيمة TRUE فيجب أن يكون هناك Callback handler - عندما يأخذ بارامتر async القيمة FALSE فالمتصفح لن يسمح للمستخدم بالقيام بأي عملية حتى يكتمل الطلب وبالتالي يمكن الاستغناء عن الـ Callback handler. المثال التالي لطلب كامل يبين ما أقصده.. يرجى الانتباه!

function getit(){
	  request = init();
	  //request.onreadystatechange = callback;
	  var url = "http://www.google.com";
	  request.open("GET", url, false);
	  request.send(null)
	  document.write(request.responseText);
	  }

طبعا الكود مختلف عما تضمنه المقال للتمييز, لكن لاحظ كيف اني قمت بكتابة كود لعرض محتويات الطلب مباشرة بعد ارساله, السبب هو ان هذا السطر (الأخير) لن يتم تنفيذه حتى يكتمل الطلب بالكامل.. لذلك نستطيع ان نميز بين الطريقتين في انهما ضروريتان وكلاهما لهما استخدام يفيد في وقت ما.

كتابة Callback Handler:

كما ذكرت منذ قليل فعندما يكون الـ async يحمل القيمة FALSE فلسنا بحاجة الى كتابة هذا الجزء, في حال العكس فاننا نطلب من المتصفح السماح للمستخدم باكمال عمله ريثما يكتمل الطلب, مثال على الحالة الاولى مثلا, عملية تحقق من بيانات عميل في موقع بنكي مثلا يقوم بعملية تحويل أموال, الحالة الثانية مثلا جلب نص موضوع ما تريد عرضه للزائر في جزء من الصفحة, كما في الصفحة الرئيسية لموقع الفريق العربي للبرمجة.

كيف نقوم بكتابة callback handler وكيف نقوم بتحديد وجوده من عدمه؟

يتم هذا من خلال استخدام الحدث onreadystatechange الذي يتم تنشيطه كلما تغيرت الحالة State للعملية قيد التنفيذ

req.onreadystatechange = callback;

يجب الانتباه الى انه يجب كتابة السابق قبل طلب open.

ماذا يحدث عندما نكتب هذا؟ وما هو هذا الـ callback؟

اعيد كتابة هذا الجزء الآن لأني لم اقتنع بما كتبته منذ قليل, لذا سأحاول التوضيح وباختصار شديد من خلال النقاط التالية

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

post-7008-1203785679.jpg

نلاحظ أن هذا يسمى Request Header, والذي يملك أقسام مختلفة لا تقتصر على الجزء الظاهر في الصورة لمزيد من المعلومات عنها يمكن مراجعة الرابط التالي:

http://en.wikipedia.org/wiki/List_of_HTTP_headers

بعد ان يتلقى السيرفر الطلب يقوم بمعالجته (لن ندخل في التفاصيل فالمعالجة ستكون بناء على الطلب المرسل) وبعد ان ينتهي من معالجة وتنفيذ الطلب يقوم بارسال رد للمتصفح الذي يكون بالشكل التالي (الرد التالي هو رد على الطلب السابق اعلاه)

post-7008-1203785685.jpg

ما يتعلق بأجاكس يهمنا في السطر الأول, فهو ما يسمى بالـ HTTP Status Code وهناك العديد من القيم لهذا البارامتر يمكن ايجاد قائمة فيها على الرابط التالي:

http://www.helpwithpcs.com/courses/html/ht...tatus_codes.htm

اغلب ما سنتعامل به من خلال اجاكس هي القيم: 200 (التي تدل على ان الطلب اكتمل بنجاح) - 400 (التي تدل على ان الطلب المرسل لم يتم التعرف عليه من قبل السيرفر ومعالجته) - 404 (ان الصفحة المطلوبة في بارامتر url غير موجودة على المسار المحدد) - 500 (حدوث مشكلة في السيرفر وبالتالي عدم اكتمال الطلب), طبعا هذا لا ينفي ان القيم التالية يمكن ان ترد ضمن مراحل عملك كمصمم.

سؤال: لماذا تهمنا هذه القيم؟ ببساطة لانه من خلالها تحدد فيما اذا اكتمل الطلب واصبح بمقدورك استخدام الرد المرسل اليك من قبل السيرفر ام ليس بعد, فكما يجب ان تدركه مهمة الـ callback هو التقاط الرد من السيرفر عند الانتهاء من معالجته.

سؤال: هل يكفي التحقق من حصولنا على القيمة 200 ؟ نعم يكفي, لكن ليس مباشرة. كيف؟ تابع

عندما يقوم السيرفر بالانتهاء من عمله سواء بالنجاح او بالفشل فانه يرسل قيمة الـ HTTP Status Code الى المستند الذي قام بارسال الطلب, نستطيع من خلال اجاكس التقاط هذا الرد من قبل السيرفر من خلال خاصة تسمى readyState, هذه الخاصة يتم تحديثها كل مرة يقوم السيرفر بارسال رد الى المستند الذي ارسل الطلب, نسمي هذا الرد response. تملك هذه الخاصة 5 قيم تحدد شكل الرد وهي بالشكل التالي:

  • 0 (uninitialized)
  • 1 (loading)
  • 2 (loaded)
  • 3 (interactive)
  • 4 (complete)

ما يهمنا في الوقت الحالي هي القيمة الخامسة, والتي تحمل القيمة "4" التي تحدد ان معالجة الطلب قد اكتملت واصبح بالامكان المتابعة.

اذا نخلص الى التالي, لكي نستطيع ان نتابع مع الرد المرسل من قبل السيرفر يجب ان تكون خاصة readyState تحمل القيمة 4 ويجب ان نكون قد حصلنا على القيمة 200 من السيرفر دليل نجاح التنفيذ, نسيت أن اذكر ان قيمة الـ HTTP Status Code نحصل عليها من خلال خاصة تسمى Status.

function callback(){
		if (request.readyState == 4) { // we could simply use "complete" instead of "4"
		if (request.status == 200) {
			.
			.
			.
		}
		}
	}

لنقم بالاطلاع الان على محتويات الملف headlines.xml قبل ان نتابع لأنه من المهم فهم بنية مستندات XML والتي سأحاول تبسيطها بصورة تهم غرض هذا المقال.

post-7008-1203785434.jpg

هذا هو محتوى الملف الذي سنقوم بقراءته, دعوني أنوه فقط إلى السطر الاول حاليا, لاحظ كيف انه يحتوي على الـ encoding والذي يملك القيمة Windows-1256 التي تسمح بعرض الحروف العربية بالشكل الأمثل. لو لم يكن هذا الجزء موجوداً لما ظهرت الحروف بالصورة المطلوبة (حتى المتصفحات ترفض مستندات XML لو لم تحوي على الجزء المتعلق بالـ encoding).

عند هذه النقطة سنضطر للانحراف قليلاً عن غاية المقال لندخل في بنية ملفات XML وطريقة جلب البيانات منها وهناك بعض الامور التي يجب ان نأخذها كمسلمات فيما يتعلق ببنية هذه الملفات:

  • بنية ملفات XML هرمية الشكل.
  • يبدأ كل مستند XML بالتصريح عنه باستخدام الشكل التالي: <? xml version = "1.0" ?> حيث يوجد اصدارين, 1.0 وهو الاكثر استخداما, والاصدار 1.1.
  • كل مستند XML يملك وسم رئيسي يضم جميع الوسوم الأخرى, لنعتبره أب وأبناء مجازاً.
  • كل ابن قد يكون أب لأبناء آخرين أو لا يكون.
  • تسمح XML باستخدام أسماء اختيارية للوسوم, فيما عدا بعض الأسماء الممنوعة مثل:

  1. لا يمكن ان يحتوي الوسم على فراغات <my name>
  2. لا يمكن ان يبدأ الوسم برقم <12boxes>
  3. لا يمكن ان يحوي الوسم على اشارات اقتباس double quotes <"ok">

  • كل وسم يملك وسم إغلاق, اللهم إلا إذا استخدمت الصورة المتمثلة في (على سبيل المثال لا الحصر):

<a ... />

التي تعمل فقط في حال كان الوسم عبارة عن وسم فارغ (اي ما سيتم تضمينه بين <a>هنــــــا فارغ</a> غير موجود). عندها لا يوجد داع لكتابة <a></a>. فقط <a />.

مثال عن بنية مستند XML, مثال آخر طبعا..

<? xml version = "1.0" encoding="ISO-8859-1" ?>
 <party>
	<guests>
		 <hani />
		 <saleh />
		 <fuad />
		 <emad />
	</guests>
 </party>

سأتابع الموضوع لاحقاً إن شاء الله

تم تعديل هذه المشاركة بواسطة Xacker في 31 مارس 2008 في 16:57

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#2

مشكور جداً على الموضوع

أنا أزداد كل يوم اقتناعاً أن هذا المنتدى يضم مبرمجين من أفضل المبرمجين على مستوى العرب إن لم نقل العالم

أنا أعتقد أن موضوع الدورة مفيد لكل مبرمج ويب و لذلك سأكون أول المنتسبين لدورتك

سأقرأ الدرس الأول و أحاول تطبيقه و أبلغك النتائج

مع تحياتي

motamiz

تقســــم الناس دنياهم و فتنتها وقد تفرد من يـهوى بدنياهُ

ما فارق الري قلباً أنت جذوتهُ و لا النعيم محباً أنت سلواهُ

#3

السلام عليكم, أي دورة أخي الكريم؟؟

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#4

كأني فهمت من كلامك أنك ستكمل الموضوع إلى أن يصبح بحث متكامل ...

أليس كذلك ؟!!! :rolleyes:

تم تعديل هذه المشاركة بواسطة motamiz في 1 أبريل 2008 في 22:38

تقســــم الناس دنياهم و فتنتها وقد تفرد من يـهوى بدنياهُ

ما فارق الري قلباً أنت جذوتهُ و لا النعيم محباً أنت سلواهُ

#5

شكرا دومك مبدع والله معلومات قيمه رغم ان موقعي بالاجاكس وتطرقت لها كثيرا لكني عرفت اشياء جديده

شكرا لك واعطيني رأبك http://www.mini-5pider.com

والله ان الاجاكس راااااااااائعه الى ابعد الحدود

[moveleft]

MiN! SpId3r SqUaD

[/moveleft]

#6
motamiz كتب:
كأني فهمت من كلامك أنك ستكمل الموضوع إلى أن يصبح بحث متكامل ...

أليس كذلك ؟!!! :rolleyes:

نعم إن شاء الله.

mini.spider كتب:
شكرا لك واعطيني رأبك http://www.mini-5pider.com

أعرف موقعك منذ أن بدأت بتصميمه :)

اعتبره جيد جداً طالما أنك تقوم ببناءه بنفسك وتتعلم كي تتابع وتكمل كل أجزاءه

بالتوفيق إن شاء الله

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#7

شكرااااااااااا لك هذا شرف لي

بان يزورني شخص مثلك

تحياتي لك

[moveleft]

MiN! SpId3r SqUaD

[/moveleft]

مواضيع مشابهة