تستخدم معظم تطبيقات الويب نموذج الطلب/الاستجابة للحصول على صفحة HTML كاملة من الخادم. غالبًا ما تكون عملية متكررة تتمثل في النقر فوق الزر، وانتظار استجابة الخادم، والنقر فوق زر آخر، ثم الانتظار مرة أخرى. باستخدام Ajax وكائن XMLHttpRequest، يمكنك استخدام نموذج طلب/استجابة لا يتطلب من المستخدم انتظار استجابة من الخادم. في هذه المقالة، يشرح بريت ماكلولين كيفية إنشاء مثيلات XMLHttpRequest التي يمكنها التكيف مع المتصفحات المختلفة، وإنشاء الطلبات وإرسالها، والاستجابة للخادم.
في المقالة السابقة في هذه السلسلة (انظر الموارد للحصول على رابط)، قدمنا تطبيقات Ajax وفحصنا المفاهيم الأساسية التي تحرك تطبيقات Ajax. في قلب هذا هناك الكثير من التقنيات التي ربما تعرفها بالفعل: JavaScript وHTML وXHTML، وقليل من HTML الديناميكي، وDOM (نموذج كائن المستند). ستقوم هذه المقالة بتكبير نقطة واحدة والتركيز على تفاصيل محددة عن Ajax.
في هذه المقالة، ستبدأ في التعرف على الكائنات وطرق البرمجة الأساسية والأساسية المتعلقة بـ Ajax: كائن XMLHttpRequest. هذا الكائن هو في الواقع مجرد خيط مشترك يمتد إلى جميع تطبيقات Ajax، وكما قد تتوقع، تحتاج إلى فهم هذا الكائن تمامًا لتحقيق إمكاناتك البرمجية الكاملة. في الواقع، ستجد أحيانًا أنه لاستخدام XMLHttpRequest بشكل صحيح، من الواضح أنه لا يمكنك استخدام XMLHttpRequest. ما الذي يجري؟
نظرة سريعة على الويب 2.0
قبل الخوض في التعليمات البرمجية، دعنا نلقي نظرة على وجهات النظر الحديثة - من المهم أن نكون واضحين للغاية بشأن مفهوم الويب 2.0. عندما تسمع مصطلح الويب 2.0، يجب عليك أولاً أن تسأل "ما هو الويب 1.0؟" على الرغم من أنه من النادر أن تسمع أشخاصًا يذكرون الويب 1.0، إلا أنه في الواقع يشير إلى الويب التقليدي بنموذج طلب واستجابة مختلف تمامًا. على سبيل المثال، انتقل إلى موقع Amazon.com وانقر فوق زر أو أدخل مصطلح بحث. يتم إرسال طلب إلى الخادم، ويتم إرجاع الاستجابة إلى المتصفح. الطلب ليس مجرد قائمة بالكتب والعناوين، بل صفحة HTML كاملة أخرى. ولذلك، قد ترى وميضًا أو اهتزازًا عندما يعيد متصفح الويب رسم الصفحة باستخدام HTML الجديد. في الواقع، الطلبات والردود تظهر بوضوح مع كل صفحة جديدة تراها.
ويب 2.0 (إلى حد كبير) يلغي هذا التفاعل المرئي ذهابًا وإيابًا. على سبيل المثال، قم بزيارة موقع مثل خرائط Google أو Flickr (راجع الموارد للحصول على روابط إلى مواقع الويب 2.0 والمواقع التي تدعم Ajax). في خرائط جوجل، على سبيل المثال، يمكنك سحب الخريطة للتكبير والتصغير مع الحد الأدنى من إعادة الرسم. وبالطبع لا تزال هناك طلبات وردود، لكنها مخفية وراء الكواليس. كمستخدم، تكون التجربة أكثر راحة وتشبه إلى حد كبير تطبيق سطح المكتب. هذا الشعور والنموذج الجديد هو ما تحصل عليه عندما يذكر شخص ما الويب 2.0.
القلق هو جعل هذه التفاعلات الجديدة ممكنة. من الواضح أنك لا تزال بحاجة إلى تقديم طلبات وتلقي استجابات، ولكن إعادة رسم HTML لكل تفاعل طلب/استجابة هو ما يخلق شعورًا بالبطء والبطء في تفاعلات الويب. لذا فمن الواضح أننا بحاجة إلى طريقة لإرسال الطلبات وتلقي الاستجابات التي تحتوي فقط على البيانات المطلوبة بدلاً من صفحة HTML بأكملها. المرة الوحيدة التي تحتاج فيها للحصول على صفحة HTML الجديدة بالكامل هي عندما تريد أن يرى المستخدم الصفحة الجديدة.
لكن معظم التفاعلات تضيف تفاصيل إلى الصفحات الموجودة، أو تعدل النص الرئيسي، أو تستبدل البيانات الأصلية. في هذه الحالات، تسمح أساليب Ajax وWeb 2.0 بإرسال البيانات واستلامها دون تحديث صفحة HTML بأكملها. بالنسبة لأولئك الذين يقضون الكثير من الوقت عبر الإنترنت، يمكن لهذه القدرة أن تجعل تطبيقاتك أسرع وأكثر استجابة، مما يجعلها تعود إلى موقعك من وقت لآخر.
مقدمة إلى XMLHttpRequest
لتحقيق هذه المعجزة الرائعة، يجب أن تكون على دراية بكائن JavaScript، وهو XMLHttpRequest. لقد كان هذا الكائن الصغير موجودًا بالفعل في العديد من المتصفحات لفترة من الوقت، وهو يقع في قلب Web 2.0 وAjax والكثير من الأشياء الأخرى التي سأغطيها في هذا العمود خلال الأشهر القليلة القادمة. لإعطائك نظرة عامة سريعة، إليك بعض الأساليب والخصائص التي سيتم استخدامها على هذا الكائن.
·open(): إنشاء طلب جديد إلى الخادم.
·إرسال (): إرسال طلب إلى الخادم.
·abort(): إحباط الطلب الحالي.
· ReadyState: يوفر حالة الاستعداد لـ HTML الحالي.
·responseText: نص استجابة الطلب الذي يتم إرجاعه بواسطة الخادم.
لا تقلق إذا كنت لا تعرف هذه (أو أيًا منها)، فسنغطي كل طريقة وخاصية في المقالات القليلة التالية. ما يجب أن تعرفه الآن هو بالضبط ما يجب فعله باستخدام XMLHttpRequest. لاحظ أن هذه الأساليب والخصائص تتعلق بإرسال الطلبات ومعالجة الاستجابات. في الواقع، إذا نظرت إلى جميع أساليب وخصائص XMLHttpRequest، فستجد أنها جميعها تتعلق بنموذج طلب/استجابة بسيط جدًا. من الواضح أننا لن نواجه كائنًا جديدًا في واجهة المستخدم الرسومية أو طريقة غامضة جدًا لإنشاء تفاعل المستخدم، بل سنستخدم طلبات بسيطة جدًا واستجابات بسيطة جدًا. قد لا يبدو الأمر كثيرًا، لكن استخدام هذا الكائن بشكل جيد يمكن أن يحدث ثورة في تطبيقك.
يتطلبالجديد البسيط
أولاً إنشاء متغير جديد وتعيين مثيل كائن XMLHttpRequest له. يعد هذا أمرًا بسيطًا مثل استخدام الكلمة الأساسية الجديدة في اسم الكائن في JavaScript، كما هو موضح في القائمة 1.
القائمة 1. إنشاء كائن XMLHttpRequest جديد
<script language="javascript" type="text/javascript">
var request = new XMLHttpRequest();
</script>
أليس الأمر صعبًا؟ تذكر أن JavaScript لا تتطلب منك تحديد أنواع المتغيرات، لذا لا تحتاج إلى القيام بما تفعله في القائمة 2 (والذي قد تفعله في لغة Java).
القائمة 2. رمز Java الزائف لإنشاء
طلب XMLHttpRequestXMLHttpRequest = new XMLHttpRequest();
لذلك في JavaScript، يمكنك إنشاء متغير باستخدام var، وإعطائه اسمًا (مثل "request")، ثم تعيين مثيل XMLHttpRequest جديد له. يمكن بعد ذلك استخدام الكائن في الوظائف.
معالجة الأخطاء
يمكن لجميع أنواع الأشياء أن تسوء بالفعل، ولا يوفر الكود أعلاه أي معالجة للأخطاء. الطريقة الأفضل هي إنشاء الكائن والخروج بأمان إذا حدث خطأ ما. على سبيل المثال، أي متصفحات قديمة (صدق أو لا تصدق، لا يزال هناك أشخاص يستخدمون الإصدارات الأقدم من Netscape Navigator) لا تدعم XMLHttpRequest، وتحتاج إلى إعلام هؤلاء المستخدمين بوجود خطأ ما. توضح القائمة 3 كيفية إنشاء هذا الكائن لإصدار تحذير JavaScript عند حدوث مشكلة.
القائمة 3. إنشاء XMLHttpRequest مع إمكانيات معالجة الأخطاء
<script language="javascript" type="text/javascript">
طلب فار = خطأ؛
يحاول {
request = new XMLHttpRequest();
} صيد (فشل) {
طلب = خطأ؛
}
إذا (!طلب)
تنبيه ("حدث خطأ أثناء تهيئة XMLHttpRequest!")؛
</script>
تأكد من فهم الخطوات التالية:
1. قم بإنشاء طلب متغير جديد وقم بتعيين قيمة خطأ له. سيتم استخدام False كشرط للحكم لاحقًا، مما يعني أن كائن XMLHttpRequest لم يتم إنشاؤه بعد.
2. أضف كتلة المحاولة/الالتقاط:
1) حاول إنشاء كائن XMLHttpRequest.
2) إذا فشل (catch (failed))، فمن المؤكد أن قيمة الطلب لا تزال خاطئة.
3. تحقق مما إذا كان الطلب لا يزال خاطئًا (لن يكون خاطئًا إذا كان كل شيء طبيعيًا).
4. في حالة حدوث مشكلة (الطلب خاطئ)، استخدم تحذير JavaScript لإعلام المستخدم بحدوث مشكلة.
الكود بسيط جدًا، وبالنسبة لمعظم مطوري JavaScript والويب، سيستغرق الأمر وقتًا أطول لفهمه حقًا بدلاً من قراءة الكود وكتابته. الآن لديك جزء من كود إنشاء كائن XMLHttpRequest الذي تم التحقق من الأخطاء فيه ويمكنه إخبارك بالخطأ الذي حدث.
يبدو أن كل شيء على ما يراممع Microsoft
، على الأقل حتى تجرب الكود باستخدام Internet Explorer. إذا قمت بتجربة مثل هذا، سترى الوضع السيئ الموضح في الشكل 1.
الشكل 1. خطأ في الإبلاغ عن Internet Explorer
من الواضح أن هناك خطأ ما، ومن الصعب أن يكون Internet Explorer متصفحًا قديمًا نظرًا لأنه يستخدمه 70% من سكان العالم. بمعنى آخر، إذا كنت لا تدعم Microsoft وInternet Explorer، فلن تتمتع بشعبية كبيرة في عالم الويب! لذلك نحن بحاجة إلى اتباع نهج مختلف مع متصفحات Microsoft.
تم التحقق من أن Microsoft تدعم Ajax، ولكن إصدار XMLHttpRequest الخاص بها له اسم مختلف. في الواقع، يطلق عليه عدة أشياء مختلفة. إذا كنت تستخدم إصدارات أحدث من Internet Explorer، فأنت بحاجة إلى استخدام الكائن Msxml2.XMLHTTP، بينما تستخدم الإصدارات الأقدم من Internet Explorer Microsoft.XMLHTTP. نحتاج إلى دعم كلا النوعين من الكائنات (بالإضافة إلى المتصفحات غير التابعة لشركة Microsoft). ألقِ نظرة على القائمة 4، التي تعتمد على التعليمات البرمجية السابقة وتضيف دعمًا لـ Microsoft.
هل مايكروسوفت متورطة؟
لقد كتب الكثير عن اهتمام ومشاركة أياكس ومايكروسوفت المتزايد في هذا المجال. في الواقع، يُقال أن أحدث إصدار من Internet Explorer من Microsoft - الإصدار 7.0، المقرر إصداره في النصف الثاني من عام 2006 - سيبدأ في دعم XMLHttpRequest مباشرةً، مما يسمح لك باستخدام الكلمة الأساسية الجديدة بدلاً من كافة تعليمات إنشاء Msxml2.XMLHTTP. ولكن لا تتحمس كثيرًا، فالمتصفحات القديمة لا تزال بحاجة إلى الدعم، لذلك لن تختفي التعليمات البرمجية عبر المتصفحات في أي وقت قريب.
القائمة 4. إضافة دعم لمتصفحات Microsoft
<script language="javascript" type="text/javascript">
طلب فار = خطأ؛
يحاول {
request = new XMLHttpRequest();
} قبض (تريمايكروسوفت) {
يحاول {
request = new ActiveXObject("Msxml2.XMLHTTP");
} قبض (othermicrosoft) {
يحاول {
request = new ActiveXObject("Microsoft.XMLHTTP");
} صيد (فشل) {
طلب = خطأ؛
}
}
}
إذا (!طلب)
تنبيه ("حدث خطأ أثناء تهيئة XMLHttpRequest!")؛
</script>
من السهل الخلط بين هذه الأقواس المتعرجة، لذلك يتم تقديم كل خطوة أدناه:
1. قم بإنشاء طلب متغير جديد وقم بتعيين قيمة false له. استخدم false كشرط الحكم، مما يعني أن كائن XMLHttpRequest لم يتم إنشاؤه بعد.
2. أضف كتلة المحاولة/الالتقاط:
1) حاول إنشاء كائن XMLHttpRequest.
2) في حالة الفشل (التقاط (trymicrosoft)):
1>حاول استخدام إصدار أحدث من متصفح Microsoft لإنشاء كائن متوافق مع Microsoft (Msxml2.XMLHTTP).
2> إذا فشلت (التقاط (othermicrosoft)) حاول إنشاء كائن متوافق مع Microsoft (Microsoft.XMLHTTP) باستخدام إصدار أقدم من متصفح Microsoft.
2) إذا فشل (catch (failed))، فمن المؤكد أن قيمة الطلب لا تزال خاطئة.
3. تحقق مما إذا كان الطلب لا يزال كاذبًا (لن يكون كاذبًا إذا سارت الأمور على ما يرام).
4. في حالة حدوث مشكلة (الطلب خاطئ)، استخدم تحذير JavaScript لإعلام المستخدم بحدوث مشكلة.
بعد تعديل الكود بهذه الطريقة واختباره باستخدام Internet Explorer، يجب أن تشاهد النموذج الذي تم إنشاؤه (بدون رسالة خطأ). وتظهر نتائج تجربتي في الشكل 2.
الشكل 2. إنترنت إكسبلورر يعمل بشكل طبيعي
الثابتة مقابل الديناميكية
ألقِ نظرة أخرى على القوائم 1 و3 و4. لاحظ أن كل هذه التعليمات البرمجية متداخلة مباشرةً داخل علامة البرنامج النصي. يُطلق على كود JavaScript مثل هذا الذي لم يتم وضعه في نص الطريقة أو الوظيفة اسم JavaScript الثابت. وهذا يعني أنه يتم تشغيل التعليمات البرمجية في وقت ما قبل عرض الصفحة للمستخدم. (على الرغم من أن المواصفات لا تعرف بدقة كاملة مدى تأثير هذا الرمز على المتصفح عند تشغيله، فمن المؤكد أنه سيتم تشغيله قبل أن يتمكن المستخدم من التفاعل مع الصفحة.) وهذه أيضًا هي الطريقة العامة لمعظم الأشخاص. يقوم مبرمجو Ajax بإنشاء كائنات XMLHttpRequest.
ومع ذلك، يمكنك أيضًا وضع هذا الرمز بطريقة مثل القائمة 5.
القائمة 5. نقل رمز إنشاء XMLHttpRequest إلى إحدى الطرق
<script language="javascript" type="text/javascript">
var request
function createRequest() {;
يحاول {
request = new XMLHttpRequest();
} قبض (تريمايكروسوفت) {
يحاول {
request = new ActiveXObject("Msxml2.XMLHTTP");
} قبض (othermicrosoft) {
يحاول {
request = new ActiveXObject("Microsoft.XMLHTTP");
} صيد (فشل) {
طلب = خطأ؛
}
}
}
إذا (!طلب)
تنبيه ("حدث خطأ أثناء تهيئة XMLHttpRequest!")؛
}
</script>
إذا كتبت التعليمات البرمجية الخاصة بك بهذه الطريقة، فستحتاج إلى استدعاء هذه الطريقة قبل التعامل مع Ajax. لذلك هناك حاجة أيضًا إلى رمز مثل القائمة 6.
القائمة 6. إنشاء الطريقة باستخدام XMLHttpRequest
<script language="javascript" type="text/javascript">
var request
function createRequest() {;
يحاول {
request = new XMLHttpRequest();
} قبض (تريمايكروسوفت) {
يحاول {
request = new ActiveXObject("Msxml2.XMLHTTP");
} قبض (othermicrosoft) {
يحاول {
request = new ActiveXObject("Microsoft.XMLHTTP");
} صيد (فشل) {
طلب = خطأ؛
}
}
}
إذا (!طلب)
تنبيه ("حدث خطأ أثناء تهيئة XMLHttpRequest!")؛
}
الدالة getCustomerInfo() {
createRequest();
// افعل شيئًا باستخدام متغير الطلب
}
</script>
المشكلة الوحيدة في هذا الرمز هو أنه يؤخر إشعار الأخطاء، ولهذا السبب لا يستخدم معظم مبرمجي Ajax هذا الأسلوب. لنفترض أن لديك نموذجًا معقدًا يحتوي على 10 أو 15 حقلاً، ومربعات تحديد، وما إلى ذلك، وتريد تنشيط بعض أكواد Ajax عندما يقوم المستخدم بإدخال نص في الحقل الرابع عشر (من الأعلى إلى الأسفل بترتيب النموذج). عند هذه النقطة، يحاول تشغيل getCustomerInfo() إنشاء كائن XMLHttpRequest، لكنه يفشل (في هذه الحالة). يظهر للمستخدم بعد ذلك تحذيرًا يخبره بوضوح أنه لا يمكنه استخدام التطبيق. لكن المستخدمين يقضون بالفعل الكثير من الوقت في إدخال البيانات في النماذج! وهذا أمر مزعج للغاية، ومن الواضح أن كونك مزعجًا لن يجذب المستخدمين للعودة إلى موقعك.
إذا كنت تستخدم JavaScript ثابتًا، فسيرى المستخدمون رسائل خطأ بسرعة كبيرة عندما ينقرون على الصفحة. وهذا مزعج أيضا، أليس كذلك؟ قد يعتقد المستخدم خطأً أن تطبيق الويب الخاص بك لا يمكن تشغيله على متصفحه. لكن من المؤكد أن هذا أفضل من قضاء 10 دقائق في إدخال المعلومات ليظهر لهم نفس الخطأ لاحقًا. لذلك، أوصي بكتابة تعليمات برمجية ثابتة للسماح للمستخدمين باكتشاف المشكلات في أقرب وقت ممكن.
بعدإرسال طلب باستخدام XMLHttpRequest
والحصول على كائن الطلب، يمكنك الدخول إلى دورة الطلب/الاستجابة. تذكر أن الغرض الوحيد من XMLHttpRequest هو السماح لك بإرسال الطلبات وتلقي الاستجابات. كل شيء آخر هو وظيفة JavaScript أو CSS أو أي تعليمات برمجية أخرى في الصفحة: تغيير واجهة المستخدم، وتبديل الصور، وتفسير البيانات التي يعرضها الخادم. بعد إعداد طلب XMLHttpRequest، يمكنك إرسال الطلب إلى الخادم.
مرحبًا بك في Sandbox
يستخدم Ajax نموذج أمان Sandbox. لذلك، يمكن لرمز Ajax (على وجه التحديد، كائن XMLHttpRequest) إرسال الطلبات إلى نفس المجال الذي يوجد فيه فقط. سنتناول المزيد حول الأمان وAjax في مقالة مستقبلية، ولكن في الوقت الحالي، عليك فقط أن تعلم أن التعليمات البرمجية التي تعمل على الجهاز المحلي يمكنها فقط تقديم طلبات إلى البرامج النصية من جانب الخادم على الجهاز المحلي. إذا كنت تريد تشغيل كود Ajax على www.breakneckpizza.com ، فيجب إرسال الطلب من برنامج نصي يعمل على www.breakneck.com .
لتعيين عنوان URL للخادم،
يجب عليك أولاً تحديد عنوان URL للخادم المتصل. هذا ليس متطلبًا خاصًا لـ Ajax، ولكن لا يزال من الضروري إنشاء الاتصال، ومن الواضح الآن أنك يجب أن تعرف كيفية إنشاء عنوان URL. في معظم التطبيقات، يتم إنشاء عنوان URL هذا من مجموعة من بعض البيانات الثابتة وبيانات من نموذج يقوم المستخدم بمعالجته. على سبيل المثال، يحصل كود JavaScript في القائمة 7 على قيمة حقل رقم الهاتف ويستخدمه لإنشاء عنوان URL.
القائمة 7. إنشاء عنوان URL للطلب
<script language="javascript" type="text/javascript">
طلب فار = خطأ؛
يحاول {
request = new XMLHttpRequest();
} قبض (تريمايكروسوفت) {
يحاول {
request = new ActiveXObject("Msxml2.XMLHTTP");
} قبض (othermicrosoft) {
يحاول {
request = new ActiveXObject("Microsoft.XMLHTTP");
} صيد (فشل) {
طلب = خطأ؛
}
}
}
إذا (!طلب)
تنبيه ("حدث خطأ أثناء تهيئة XMLHttpRequest!")؛
وظيفة getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
}
</script>
لا يوجد شيء يصعب فهمه هنا. أولاً، يقوم الكود بإنشاء هاتف متغير جديد ويعين له قيمة حقل النموذج بالمعرف "الهاتف". تعرض القائمة 8 ملف XHTML لهذا النموذج، حيث يمكنك رؤية حقل الهاتف وسمة المعرف الخاصة به.
القائمة 8. شكل بيتزا بريك نيك
<الجسم>
<p><img src="breakneck-logo_4c.gif" alt="بيتزا كسر الرقبة" /></p>
<إجراء النموذج = "POST">
<p>أدخل رقم هاتفك:
<نوع الإدخال = "نص" الحجم = "14" اسم = "الهاتف" معرف = "الهاتف"
onChange = "getCustomerInfo ()؛ />".
</ص>
<p>سيتم تسليم طلبك</p>
<div id="address"></div>
<p>اكتب طلبك هنا:</p>
<p><textarea name="order"rows="6" cols="50" id="order"></textarea></p>
<p><input type="submit" value="اطلب بيتزا" id="submit" /></p>
</النموذج>
</body>
لاحظ أيضًا أنه عندما يقوم المستخدم بإدخال رقم هاتف أو تغيير رقم الهاتف، يتم تشغيل طريقة getCustomerInfo() الموضحة في القائمة 8. تحصل هذه الطريقة على رقم الهاتف وتقوم بإنشاء سلسلة عنوان URL مخزنة في متغير عنوان url. تذكر، نظرًا لأن رمز Ajax موجود في وضع الحماية ولا يمكنه الاتصال إلا بنفس المجال، فليست هناك حاجة في الواقع إلى اسم المجال في عنوان URL. يسمى البرنامج النصي في هذا المثال /cgi-local/lookupCustomer.php. وأخيرًا، يتم إلحاق رقم الهاتف بالبرنامج النصي كمعلمة GET: "phone = + escape(phone).
إذا لم تكن قد شاهدت طريقة الهروب () من قبل، فسيتم استخدامها للهروب من أي أحرف لا يمكن إرسالها بشكل صحيح بنص واضح. على سبيل المثال، سيتم تحويل المسافات في أرقام الهواتف إلى الأحرف %20، مما يسمح بتمرير هذه الأحرف في عنوان URL.
يمكنك إضافة العديد من المعلمات حسب الحاجة. على سبيل المثال، إذا كنت بحاجة إلى إضافة معلمة أخرى، فما عليك سوى إلحاقها بعنوان URL وفصلها بحرف علامة العطف (&) [يتم فصل المعلمة الأولى عن اسم البرنامج النصي بعلامة استفهام (؟)].
فتح الطلب
بمجرد حصولك على عنوان URL للاتصال به، يمكنك تكوين الطلب. يمكن تحقيق ذلك باستخدام الأسلوب open() للكائن XMLHttpRequest. تحتوي هذه الطريقة على خمس معلمات:
نوع الطلب: نوع الطلب المراد إرساله. القيم النموذجية هي GET أو POST، ولكن يمكن أيضًا إرسال طلب HEAD.
URL: عنوان URL للاتصال به.
غير متزامن: صحيح إذا كنت تريد استخدام اتصال غير متزامن، وخطأ إذا كنت تريد استخدام اتصال غير متزامن. هذه المعلمة اختيارية وتكون القيمة الافتراضية صحيحة.
اسم المستخدم: إذا كانت المصادقة مطلوبة، يمكنك تحديد اسم المستخدم هنا. هذه المعلمة الاختيارية ليس لها قيمة افتراضية. كلمة المرور: إذا كانت المصادقة مطلوبة، يمكنك تحديد كلمة مرور هنا. هذه المعلمة الاختيارية ليس لها قيمة افتراضية.
هل الفتح () مفتوح؟
لا يتفق مطورو الإنترنت على ما تفعله طريقة open() بالضبط. ولكن في الواقع لا يفتح الطلب. إذا كنت تراقب الشبكة ونقل البيانات بين صفحة XHTML/Ajax والبرنامج النصي المتصل بها، فلن ترى أي اتصال عند استدعاء الأسلوب open(). من غير الواضح سبب اختيار هذا الاسم، لكن من الواضح أنه ليس اختيارًا جيدًا.
عادة ما يتم استخدام المعلمات الثلاثة الأولى. في الواقع، حتى لو كان الاتصال غير المتزامن مطلوبًا، فيجب تحديد المعلمة الثالثة على أنها "صحيحة". هذا هو الوضع الافتراضي، ولكن من الأسهل فهم الإصرار على التحديد الصريح لما إذا كان الطلب غير متزامن أم متزامن.
عادةً ما يؤدي دمج هذه العناصر معًا إلى إنشاء سطر من التعليمات البرمجية مثل ذلك الموضح في القائمة 9.
القائمة 9. فتح
وظيفة الطلب getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
}
بمجرد إعداد عنوان URL، يصبح الباقي سهلاً. بالنسبة لمعظم الطلبات، يكون GET كافيًا (سترى متى يكون POST مطلوبًا في مقالة لاحقة)، بالإضافة إلى عنوان URL، وهذا كل ما تحتاجه لاستخدام الأسلوب open().
تحدي عدم التزامن
في المقالة التالية من هذه السلسلة، سأقضي الكثير من الوقت في الكتابة واستخدام التعليمات البرمجية غير المتزامنة، ولكن يجب أن تفهم سبب أهمية المعلمة الأخيرة لـ open(). في نموذج الطلب/الاستجابة العام، مثل Web 1.0، يقوم العميل (متصفح أو رمز يعمل على الجهاز المحلي) بتقديم طلب إلى الخادم. الطلب متزامن، بمعنى آخر، ينتظر العميل الرد من الخادم. عندما ينتظر العميل، سيتم إعلامك بالانتظار بشكل ما على الأقل:
· الساعة الرملية (خاصة في نظام التشغيل Windows).
· الكرة الدوارة (عادةً على أجهزة Mac).
· يتجمد التطبيق بشكل أساسي ثم بعد فترة يتغير المؤشر.
وهذا هو بالضبط السبب الذي يجعل تطبيقات الويب تبدو بطيئة أو بطيئة، أي الافتقار إلى التفاعل الحقيقي. عند الضغط على الزر، يصبح التطبيق غير قابل للاستخدام بشكل فعال حتى تتم الاستجابة للطلب الذي تم تشغيله للتو. إذا كان الطلب يتطلب الكثير من معالجة الخادم، فقد يكون وقت الانتظار طويلاً (على الأقل في عالم المعالجات المتعددة هذا، عالم DSL-no-wait).
الطلبات غير المتزامنة لا تنتظر الرد من الخادم. يستمر التطبيق في العمل بعد إرسال الطلب. لا يزال بإمكان المستخدمين إدخال البيانات في نموذج الويب أو حتى التنقل بعيدًا عن النموذج. لا توجد كرات تدور أو ساعات رملية، ولا يتجمد التطبيق بشكل ملحوظ. يستجيب الخادم للطلب بهدوء، وعندما يتم ذلك، يخبر مقدم الطلب الأصلي أن المهمة قد انتهت (سترى متى سيتم ذلك). والنتيجة هي تطبيق يبدو أقل تباطؤًا أو تباطؤًا وأكثر استجابة وتفاعلية ويشعر بأنه أسرع بكثير. وهذا مجرد جزء واحد من الويب 2.0، ولكنه جزء مهم. لا تستطيع جميع مكونات واجهة المستخدم الرسومية القديمة ونماذج تصميم الويب التغلب على نموذج الطلب/الاستجابة البطيء والمتزامن.
إرسال الطلبات
بمجرد تكوينها باستخدام open()، يمكنك إرسال الطلبات. لحسن الحظ، طريقة إرسال الطلبات لها اسم أكثر ملاءمة من open(): إنها send().
يحتوي التابع send() على معلمة واحدة فقط، وهي المحتوى الذي سيتم إرساله. لكن قبل التفكير في هذه الطريقة، تذكر أنك قمت بالفعل بإرسال البيانات من خلال عنوان URL نفسه:
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
على الرغم من أنه يمكنك استخدام send() لإرسال البيانات ولكن من الممكن أيضًا إرسال البيانات عبر عنوان URL نفسه. في الواقع، مع طلبات GET (التي تحدث في حوالي 80% من تطبيقات Ajax النموذجية)، يصبح إرسال البيانات باستخدام عنوان URL أسهل بكثير. إذا كنت بحاجة إلى إرسال معلومات آمنة أو XML، فقد ترغب في التفكير في استخدام send() لإرسال المحتوى (ستتم مناقشة البيانات الآمنة ورسائل XML في المقالات اللاحقة في هذه السلسلة). إذا لم تكن بحاجة إلى تمرير البيانات من خلال send()، فما عليك سوى تمرير null كمعلمة لهذه الطريقة. لذلك ستجد أن هذا هو كل ما عليك فعله في الأمثلة الواردة في هذه المقالة (انظر القائمة 10).
القائمة 10. إرسال
وظيفة الطلب getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.send(null);
}
تحديد أسلوب رد الاتصال
هناك القليل جدًا مما نقوم به الآن سواء كان جديدًا أو ثوريًا أو غير متزامن. يجب الاعتراف بأن الكلمة الأساسية الصغيرة "صحيح" في طريقة open() تنشئ طلبًا غير متزامن. لكن بخلاف ذلك، لا تختلف التعليمات البرمجية عن البرمجة باستخدام Java servlets وJSP أو PHP أو Perl. إذن ما هو السر الأكبر في Ajax وWeb 2.0؟ السر يكمن في خاصية بسيطة onreadystatechange لـ XMLHttpRequest.
تأكد من فهم التدفق في هذا الرمز أولاً (راجع القائمة 10 إذا لزم الأمر). بناء طلبه ومن ثم تقديم الطلب. بالإضافة إلى ذلك، نظرًا لأن الطلب غير متزامن، فإن طريقة JavaScript (getCustomerInfo() في المثال) لا تنتظر الخادم. لذلك سيستمر تنفيذ التعليمات البرمجية، أي أنه سيتم الخروج من الطريقة وسيتم إرجاع التحكم إلى النموذج. يمكن للمستخدم الاستمرار في إدخال المعلومات ولا ينتظر التطبيق الخادم.
وهذا يثير سؤالاً مثيرًا للاهتمام: ماذا يحدث بعد أن يكمل الخادم الطلب؟ الجواب هو أن لا شيء يحدث، على الأقل بالنسبة للكود الحالي! من الواضح أن هذا لن ينجح، لذا يحتاج الخادم إلى نوع من الإرشادات حول ما يجب فعله بعد الانتهاء من معالجة الطلب المرسل إليه عبر XMLHttpRequest.
الوظائف المرجعية في JavaScript:
JavaScript هي لغة مكتوبة بشكل ضعيف ويمكنك استخدام المتغيرات للإشارة إلى أي شيء. لذا، إذا قمت بتعريف دالة updatePage()، فإن JavaScript تتعامل أيضًا مع اسم الوظيفة كمتغير. بمعنى آخر، يمكنك الإشارة إلى الوظيفة في التعليمات البرمجية الخاصة بك باستخدام اسم المتغير updatePage.
القائمة 11. تعيين
وظيفة طريقة رد الاتصال getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
من المهم ملاحظة مكان تعيين هذه الخاصية في الكود - يتم تعيينها قبل استدعاء send(). ويجب ضبط هذه الخاصية قبل إرسال الطلب حتى يتمكن الخادم من مشاهدتها بعد الرد على الطلب المكتمل. الآن كل ما تبقى هو كتابة طريقة updatePage()، وهو محور القسم الأخير من هذه المقالة.
يستجيب خادم المعالجة
للطلب، ويستخدم المستخدم نموذج الويب بسعادة (أثناء معالجة الخادم للطلب)، والآن أكمل الخادم معالجة الطلب. ينظر الخادم إلى سمة onreadystatechange لتحديد الطريقة التي سيتم الاتصال بها. بخلاف ذلك، تعامل مع تطبيقك مثل أي تطبيق آخر، سواء كان غير متزامن أم لا. بمعنى آخر، ليس عليك بالضرورة اتخاذ إجراء خاص لكتابة طريقة تستجيب للخادم، كل ما تحتاجه هو تغيير النموذج، أو السماح للمستخدم بزيارة عنوان URL آخر أو القيام بكل ما يحتاجه خادم الاستجابة. نركز في هذا القسم على الاستجابات للخادم والإجراء النموذجي - تغيير جزء من النموذج الذي يراه المستخدم على الفور.
عمليات الاسترجاعات وAjax
لقد رأينا الآن كيفية إخبار الخادم بما يجب فعله عند الانتهاء: قم بتعيين خاصية onreadystatechange الخاصة بكائن XMLHttpRequest على اسم الوظيفة التي سيتم تشغيلها. بهذه الطريقة، سيتم استدعاء الوظيفة تلقائيًا بعد أن يقوم الخادم بمعالجة الطلب. ليست هناك حاجة أيضًا للقلق بشأن أي معلمات للوظيفة. نبدأ بطريقة بسيطة، كما هو موضح في القائمة 12.
القائمة 12. رمز طريقة رد الاتصال
<script language="javascript" type="text/javascript">
طلب فار = خطأ؛
يحاول {
request = new XMLHttpRequest();
} قبض (تريمايكروسوفت) {
يحاول {
request = new ActiveXObject("Msxml2.XMLHTTP");
} قبض (othermicrosoft) {
يحاول {
request = new ActiveXObject("Microsoft.XMLHTTP");
} صيد (فشل) {
طلب = خطأ؛
}
}
}
إذا (!طلب)
تنبيه ("حدث خطأ أثناء تهيئة XMLHttpRequest!")؛
وظيفة getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
وظيفة تحديث الصفحة () {
تنبيه ("انتهى الخادم!")؛
}
</script>
فهو يصدر فقط بعض التحذيرات البسيطة لإخبارك عندما يكمل الخادم مهمته. جرب هذا الرمز على صفحة الويب الخاصة بك وافتحه في المتصفح (راجع القائمة 8 إذا كنت تريد رؤية XHTML في هذا المثال). أدخل رقم الهاتف ثم اترك الحقل، ستظهر لك نافذة تحذير منبثقة (كما هو موضح في الشكل 3)، ولكن انقر فوق "موافق" وسوف تظهر مرة أخرى...
الشكل 3. رمز Ajax للتحذير المنبثق
اعتمادًا على المتصفح، قد ترى تحذيرين أو ثلاثة أو حتى أربعة تحذيرات قبل أن يتوقف النموذج عن الظهور. ماذا يحدث هنا؟ اتضح أننا لم نأخذ في الاعتبار حالة استعداد HTTP، والتي تعد جزءًا مهمًا من دورة الطلب/الاستجابة.
حالة استعداد HTTP
كما ذكرنا سابقًا، يبحث الخادم عن الطريقة التي سيتم استدعاؤها في سمة onreadystatechange الخاصة بـ XMLHttpRequest بعد إكمال الطلب. وهذا صحيح، ولكنه غير كامل. في الواقع، فإنه يستدعي هذه الطريقة في كل مرة تتغير فيها حالة جاهزية HTTP. ماذا يعني هذا؟ يجب عليك أولاً فهم حالة استعداد HTTP.
تمثل حالة جاهزية HTTP حالة الطلب أو حالته. يتم استخدامه لتحديد ما إذا كان الطلب قد بدأ، أو تلقى استجابة، أو تم إكمال نموذج الطلب/الاستجابة. يمكن أن يساعد أيضًا في تحديد ما إذا كان من الآمن قراءة نص الاستجابة أو البيانات المقدمة من الخادم. هناك خمس حالات استعداد يجب أن تكون على دراية بها في تطبيقات Ajax:
·0: لم يتم إصدار الطلب (قبل استدعاء open()).
·1: تم إنشاء الطلب ولكن لم يتم إرساله بعد (قبل استدعاء send()).
·2: تم إرسال الطلب وهو قيد المعالجة (يمكن عادة الحصول على رأس المحتوى من الرد).
·3: تمت معالجة الطلب وعادةً ما تتوفر بعض البيانات في الرد، لكن الخادم لم يكمل الاستجابة.
·4: الاستجابة كاملة ويمكنك الوصول إلى استجابة الخادم واستخدامها.
كما هو الحال مع معظم المشكلات عبر المستعرضات، لا يتم استخدام حالات الاستعداد هذه بشكل متسق. قد تتوقع أن تنتقل حالة الاستعداد للمهمة من 0 إلى 1، إلى 2، إلى 3، إلى 4، ولكن هذا نادرًا ما يحدث. لا تُبلغ بعض المتصفحات أبدًا عن 0 أو 1، ولكنها تبدأ مباشرةً بالرقم 2، ثم 3 و4. تقوم المتصفحات الأخرى بالإبلاغ عن جميع الحالات. يقوم الآخرون بالإبلاغ عن حالة الاستعداد 1 عدة مرات. كما رأينا في القسم السابق، يستدعي الخادم updatePage() عدة مرات، وينبثق مربع تحذير في كل مرة يتم استدعاؤه - قد يكون مختلفًا عما هو متوقع!
بالنسبة لبرمجة Ajax، الحالة الوحيدة التي تحتاج إلى المعالجة المباشرة هي حالة الاستعداد 4، مما يشير إلى أن استجابة الخادم كاملة وأن بيانات الاستجابة آمنة للاستخدام. وبناءً على ذلك، يجب أن يبدو السطر الأول في طريقة رد الاتصال مثل القائمة 13.
القائمة 13. التحقق من
وظيفة الاستعداد updatePage() {
إذا (request.readyState == 4)
تنبيه ("انتهى الخادم!")؛
}
بعد التعديل، يمكنك التأكد من اكتمال معالجة الخادم. حاول تشغيل الإصدار الجديد من كود Ajax وسترى الآن رسالة التحذير معروضة مرة واحدة فقط، كما هو متوقع.
رموز حالة HTTP
على الرغم من أن الكود الموجود في القائمة 13 يبدو جيدًا، إلا أن هناك مشكلة - ماذا لو استجاب الخادم للطلب وأكمل المعالجة ولكنه أبلغ عن خطأ؟ انتبه إلى أن التعليمات البرمجية من جانب الخادم يجب أن تفهم أنه يتم استدعاؤها بواسطة Ajax أو JSP أو نماذج HTML العادية أو أنواع أخرى من التعليمات البرمجية، ولكن يمكنها فقط الإبلاغ عن المعلومات باستخدام الطرق التقليدية الخاصة بالويب. في عالم الويب، يمكن لرمز HTTP التعامل مع المشكلات المختلفة التي قد تحدث في الطلب.
على سبيل المثال، لا بد أنك واجهت الموقف الذي أدخلت فيه طلب عنوان URL خاطئًا وحصلت على رمز الخطأ 404، مما يعني أن الصفحة غير موجودة. يعد هذا مجرد واحد من رموز الأخطاء العديدة التي يمكن تلقيها من خلال طلب HTTP (راجع الرابط الموجود في الموارد للحصول على قائمة كاملة برموز الحالة). 403 و401، اللذان يشيران إلى أن البيانات التي يتم الوصول إليها محمية أو محظورة، شائعة أيضًا. وفي كلتا الحالتين، يتم الحصول على رموز الخطأ هذه من الاستجابة المكتملة. بمعنى آخر، قام الخادم بتنفيذ الطلب (أي أن حالة استعداد HTTP هي 4) ولكنه لم يُرجع البيانات التي توقعها العميل.
لذلك، بالإضافة إلى حالة الاستعداد، تحتاج أيضًا إلى التحقق من حالة HTTP. رمز الحالة المتوقع هو 200، مما يعني أن كل شيء سار على ما يرام. إذا كانت حالة الاستعداد هي 4 ورمز الحالة هو 200، فيمكنك معالجة بيانات الخادم، ويجب أن تكون البيانات هي البيانات المطلوبة (بدلاً من الأخطاء أو المعلومات الأخرى التي بها مشكلات). لذلك، نحتاج أيضًا إلى إضافة التحقق من الحالة في طريقة رد الاتصال، كما هو موضح في القائمة 14.
القائمة 14. التحقق من
وظيفة رمز حالة HTTP updatePage() {
إذا (request.readyState == 4)
إذا (request.status == 200)
تنبيه ("انتهى الخادم!")؛
}
لإضافة معالجة أكثر قوة للأخطاء ومحاولة تجنب التعقيد الزائد عن طريق إضافة فحص أو اثنين لرمز الحالة، قم بإلقاء نظرة على الإصدار المعدل من updatePage() في القائمة 15.
القائمة 15. أضف القليل
من وظيفة التحقق من الأخطاء updatePage() {
إذا (request.readyState == 4)
إذا (request.status == 200)
تنبيه ("انتهى الخادم!")؛
وإلا إذا (request.status == 404)
تنبيه("عنوان URL للطلب غير موجود");
آخر
تنبيه ("خطأ: رمز الحالة هو" + request.status)؛
}
الآن قم بتغيير عنوان URL في getCustomerInfo() إلى عنوان URL غير موجود وشاهد ما سيحدث. من المفترض أن تظهر لك رسالة تحذير تفيد بأن عنوان URL المطلوب غير موجود - رائع! من الصعب التعامل مع جميع شروط الخطأ ، ولكن هذا التغيير الصغير يمكن أن يغطي 80 ٪ من المشكلات في تطبيق الويب النموذجي.
تضمنقراءة نص الاستجابة
الآن معالجة الطلب (عبر الحالة الجاهزة) ، أعطى الخادم استجابة طبيعية (عبر رمز الحالة) ، وأخيراً يمكننا معالجة البيانات التي يتم إرجاعها بواسطة الخادم. يتم تخزين البيانات التي تم إرجاعها في خاصية BesponseText لكائن XMLHTTPrequest.
يتم ترك محتوى النص في مسؤولية ، مثل التنسيق والطول ، غامضة عن قصد. وبهذه الطريقة ، يمكن للخادم تعيين النص على أي شيء. على سبيل المثال ، قد يقوم أحد البرامج النصي بإرجاع قيم مفصولة بفاصلة ، وآخر يستخدم أنبوبًا (الحرف |) لفصل القيم ، وإرجاع سلسلة نصية أخرى. الأمر متروك للخادم لتحديد إلى أين يذهب.
في المثال المستخدم في هذه المقالة ، يقوم الخادم بإرجاع الطلب الأخير للعميل وعنوان العميل ، مفصولة بحرف الأنابيب. ثم يتم استخدام الطلب والعنوان لضبط قيم العناصر في النموذج.
قائمة 16. معالجة
وظيفة استجابة الخادم تحديث page () {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.ResponSetext.split ("|") ؛
document.getElementById ("Order"). value = response [0] ؛
document.getElementById ("العنوان"). innerhtml =
استجابة [1] .replace (/ n/g ، "") ؛
} آخر
التنبيه ("الحالة هي" + request.status) ؛
}
}
أولاً ، احصل على المسؤولية وقسمه من الأنبوب باستخدام طريقة JavaScript Split (). يتم وضع الصفيف الناتج استجابة. يتم الوصول إلى القيمة الأولى في المصفوفة - الترتيب السابق - باستخدام الاستجابة [0] ويتم تعيينها على قيمة الحقل مع معرف "الطلب". يتطلب استجابة القيمة الثانية [1] ، عنوان العميل ، المزيد من المعالجة. نظرًا لأن الخطوط الموجودة في العنوان يتم فصلها بواسطة فواصل الخطوط العادية (أحرف " n") ، يحتاج الرمز إلى استخدام فواصل الخط على طراز XHTML <BR /> بدلاً من ذلك. تتم عملية الاستبدال باستخدام دالة REPLICE () والتعبيرات العادية. أخيرًا ، يتم استخدام النص المعدل كـ HTML الداخلي في نموذج HTML Div. والنتيجة هي أن النموذج يتم تحديثه فجأة مع معلومات العميل ، كما هو موضح في الشكل 4.
الشكل 4. كسر شكل الرقبة بعد تلقي بيانات العميل
قبل إنهاء هذا المقال ، أود تقديم سمة أخرى مهمة أخرى لـ XMLHTTPrequest ، Responsexml. تحتوي هذه الخاصية على (كما قد تكون قد خمنت) استجابة XML إذا اختار الخادم استخدام استجابة XML. تختلف معالجة استجابات XML تمامًا عن معالجة النص العادي ، والتي تتضمن تحليلًا ونموذج كائن المستند (DOM) وغيرها من المشكلات. سيتم تغطية XML في مقال لاحق. ولكن نظرًا لأن Responsexml عادة ما تتم مناقشة مع BesponseText ، فإنه يستحق ذكرًا هنا. بالنسبة للعديد من تطبيقات Ajax البسيطة ، ستسدد Countext ، ولكن سترى قريبًا أنه يمكن التعامل مع XML بشكل جيد مع تطبيقات AJAX.
خاتمة
قد تتعب قليلاً من XMLHTTPREQUEST. لكنك ستستخدم هذا الكائن مرارًا وتكرارًا في كل صفحة وتطبيق تكتبه باستخدام AJAX. بصراحة ، هناك شيء يمكن قوله عن XMLHTTPrequest. ستقدم المقالة التالية كيفية استخدام POST والحصول على طلبات لتعيين رؤوس المحتوى في الطلبات وقراءة رؤوس المحتوى من استجابات الخادم ، وفهم كيفية تشفير الطلبات ومعالجة XML في نموذج الطلب/الاستجابة.
في وقت لاحق سوف نقدم صناديق أدوات Ajax المشتركة. تخفي صناديق الأدوات هذه بالفعل العديد من التفاصيل الموضحة في هذه المقالة ، مما يجعل برمجة Ajax أسهل. قد تتساءل لماذا تحتاج إلى ترميز التفاصيل ذات المستوى المنخفض عندما يكون هناك العديد من صناديق الأدوات الموجودة هناك. الجواب هو أنه من الصعب اكتشاف المشكلات في التطبيق دون معرفة ما يفعله التطبيق.
لذلك لا تتجاهل التفاصيل أو ببساطة تصفح ، وإذا حدث خطأ ما في صندوق الأدوات المفيد والرائع ، فلن تضطر إلى خدش رأسك أو إرسال بريد إلكتروني للدعم. إذا فهمت كيفية استخدام XMLHTTPrequest مباشرة ، فستجد أنه من السهل تصحيح وأغرب المشكلات الغريبة. يعد صندوق الأدوات جيدًا فقط إذا سمحت له بحل مشاكلك.
لذا يرجى التعرف على xmlhttprequest. في الواقع ، إذا كان لديك رمز AJAX الذي يستخدم صندوق الأدوات ، فحاول إعادة كتابته باستخدام كائن XMLHTTPrequest وخصائصه وطرقه. هذا تمرين جيد لمساعدتك على فهم المبادئ بشكل أفضل.
ستناقش المقالة التالية هذا الكائن بشكل أكبر ، واستكشاف بعض خصائصه الأكثر إثارة للاهتمام (مثل الاستجابة xml) ، وكيفية استخدام طلبات النشر وإرسال البيانات بتنسيقات مختلفة. يرجى البدء في كتابة الرمز وسنناقشه مرة أخرى في شهر واحد.