2. الأساسيات
في هذا الفصل، نقدم أساسيات برمجة الويب. ويهدف بشكل أساسي إلى تعريف القارئ بالمبادئ الرئيسية لبرمجة الويب التي لا تعتمد على التكنولوجيا المحددة المستخدمة لتنفيذها. ويقدم العديد من الأمثلة التي يُنصح بتجربتها من أجل "الانغماس" تدريجيًا في فلسفة تطوير الويب. يتم عرض الأدوات المجانية اللازمة لاختبارها في نهاية الوثيقة في الملحق المعنون "أدوات الويب".
2.1. مكونات تطبيق الويب
Machine Serveur

15جهاز العميل
رقم | الدور | أمثلة شائعة |
OS الخادم | Linux، Windows | |
خادم الويب | أباتشي (لينكس، ويندوز) IIS (NT)، PWS(Win9x)، Cassini (Windows+منصة .NET) | |
نصوص برمجية يتم تنفيذها على جانب الخادم. يمكن تنفيذها بواسطة وحدات الخادم أو بواسطة برامج خارجية (CGI). | PERL (Apache، IIS، PWS) VBSCRIPT (IIS، PWS) JAVASCRIPT (IIS، PWS) PHP (Apache، IIS، PWS) JAVA (Apache، IIS، PWS) C#، VB.NET (IIS) | |
قاعدة البيانات - يمكن أن تكون على نفس الجهاز الذي يعمل عليه البرنامج أو على جهاز آخر عبر الإنترنت. | Oracle (Linux، Windows) MySQL (Linux، Windows) Postgres (Linux، Windows) Access (Windows) SQL Server (ويندوز) | |
OS العميل | Linux، Windows | |
متصفح الويب | Netscape، Internet Explorer، Mozilla، Opera | |
نصوص برمجية يتم تنفيذها من جانب العميل داخل المتصفح. لا تتمتع هذه النصوص البرمجية بأي وصول إلى أقراص جهاز العميل. | VBscript (IE) جافا سكريبت (IE، نيتسكيب) PerlScript (IE) التطبيقات الصغيرة JAVA |
2.2. تبادل البيانات في تطبيق ويب مع نموذج

جهاز العميل جهاز الخادم
رقم | الدور |
يطلب المتصفح URL لأول مرة (http://machine/url). لم يتم تمرير أي معلمات. | |
يرسل له خادم الويب صفحة الويب الخاصة بـ URL. قد تكون هذه الصفحة ثابتة أو مولدة ديناميكيًا بواسطة برنامج نصي للخادم (SA) قد يكون استخدم محتوى قواعد البيانات (SB، SC). هنا، سيكتشف البرنامج النصي أن URL قد طُلبت دون تمرير معلمات، وسيقوم بإنشاء الصفحة الأولية WEB. يتلقى المتصفح الصفحة ويعرضها (CA). وقد تمكنت البرامج النصية على جانب المتصفح (CB) من تعديل الصفحة الأولية التي أرسلها الخادم. بعد ذلك، من خلال التفاعلات بين المستخدم (CD) والبرامج النصية (CB)، سيتم تعديل صفحة الويب. سيتم ملء النماذج على وجه الخصوص. | |
يقوم المستخدم بالتحقق من صحة بيانات النموذج التي يجب إرسالها بعد ذلك إلى خادم الويب. يطلب المتصفح إعادة طلب URL الأولي أو طلبًا آخر حسب الحالة، ويقوم في الوقت نفسه بإرسال قيم النموذج إلى الخادم. ويمكنه استخدام طريقتين لهذا الغرض، هما GET و POST. عند استلام طلب العميل، يقوم الخادم بتشغيل البرنامج النصي (SA) المرتبط بـ URL المطلوب، وهو البرنامج النصي الذي سيكتشف المعلمات ويعالجها. | |
يقدم الخادم الصفحة WEB التي تم إنشاؤها بواسطة البرنامج (SA، SB، SC). هذه الخطوة مطابقة للخطوة 2 السابقة. تتم التبادلات الآن وفقًا للخطوتين 2 و 3. |
2.3. Notations
فيما يلي، سنفترض أنه تم تثبيت عدد معين من الأدوات وسنستخدم الترميزات التالية:
الرمز | المعنى |
جذر شجرة الخادم Apache | |
جذر صفحات الويب التي يقدمها Apache. يجب أن توجد صفحات الويب تحت هذا الجذر. وبالتالي، فإن URL http://localhost/page1.htm يتوافق مع الملف <apache-DocumentRoot>\page1.htm. | |
جذر الشجرة المرتبط بالاسم المستعار cgi-bin وحيث يمكن وضع نصوص برمجية CGI لـ Apache. وبالتالي، فإن URL http://localhost/cgi-bin/test1.pl يتوافق مع الملف <apache-cgi-bin>\test1.pl. | |
جذر صفحات الويب التي يتم تقديمها بواسطة IIS أو PWS أو Cassini. يجب أن توجد صفحات الويب تحت هذه الجذر. وبالتالي، فإن URL http://localhost/page1.htm يتوافق مع الملف <IIS-DocumentRoot>\page1.htm. | |
جذر شجرة لغة Perl. عادةً ما يوجد الملف القابل للتنفيذ perl.exe في <perl>\bin. | |
جذر شجرة لغة PHP. عادةً ما يوجد الملف القابل للتنفيذ php.exe في <php>. | |
جذر شجرة java. توجد الملفات التنفيذية المرتبطة بـ java في <java>\bin. | |
جذر خادم Tomcat. توجد أمثلة على السيرفلتات في <tomcat>\webapps\examples\servlets وأمثلة على الصفحات في JSP في <tomcat>\webbapps\examples\jsp |
يرجى الرجوع إلى الملحق الذي يقدم مساعدة في تثبيت كل من هذه الأدوات.
2.4. صفحات الويب الثابتة، صفحات الويب الديناميكية
يتم تمثيل الصفحة الثابتة بملف HTML. أما الصفحة الديناميكية، فيتم إنشاؤها "على الفور" بواسطة خادم الويب. نقدم لكم في هذه الفقرة اختبارات متنوعة باستخدام خوادم ويب مختلفة ولغات برمجة مختلفة لإظهار عالمية مفهوم الويب. سنستخدم خادمين للويب هما Apache و IIS. على الرغم من أن IIS هو منتج تجاري، إلا أنه متوفر في نسختين أكثر محدودية ولكنهما مجانيتان:
- PWS لأجهزة Win9x
- Cassini لأجهزة Windows200 و XP
عادةً ما يكون المجلد <IIS-DocumentRoot> هو المجلد [lecteur:\inetpub\wwwroot] حيث [lecteur] هو القرص (C، D، ...) الذي تم تثبيت IIS عليه. وينطبق الأمر نفسه على PWS. بالنسبة لـ Cassini، يعتمد المجلد <IIS-DocumentRoot> على الطريقة التي تم بها تشغيل الخادم. في الملحق، يظهر أنه يمكن تشغيل خادم Cassini في نافذة Dos (أو عن طريق اختصار) بالطريقة التالية:
تقبل التطبيق [WebServer]، المعروف أيضًا باسم خادم الويب Cassini، ثلاثة معلمات:
- /port: رقم منفذ خدمة الويب. يمكن أن يكون أي رقم. القيمة الافتراضية هي 80
- /path: المسار الفعلي لمجلد على القرص
- /vpath: المجلد الافتراضي المرتبط بالمجلد الفعلي السابق. يجب الانتباه إلى أن الصيغة ليست /path=المسار بل /vpath:المسار، على عكس ما يذكره لوحة المساعدة أعلاه.
إذا تم تشغيل Cassini بالطريقة التالية:
فإن المجلد P هو جذر شجرة الويب لخادم Cassini. وبالتالي، فإن هذا المجلد هو الذي يشير إليه <IIS-DocumentRoot>. وهكذا في المثال التالي:
سيعمل خادم Cassini على المنفذ 80 وجذر شجرته <IIS-DocumentRoot> هو المجلد [d:\data\devel\webmatrix]. يجب أن توجد صفحات الويب المراد اختبارها تحت هذا الجذر.
فيما يلي، سيتم تمثيل كل تطبيق ويب بملف واحد يمكن إنشاؤه باستخدام أي ملف نصي. لا يلزم وجود IDE.
2.4.1. صفحة ثابتة HTML (لغة ترميز HyperText)
لنأخذ الكود HTML التالي:
<html>
<head>
<title>essai 1 : une page statique</title>
</head>
<body>
<center>
<h1>Une page statique...</h1>
</body>
</html>
الذي ينتج الصفحة التالية:
الاختبارات

اختبار 1
- تشغيل خادم Apache
- وضع البرنامج النصي essai1.html في <apache-DocumentRoot>
- عرض URL http://localhost/essai1.html باستخدام متصفح
- إيقاف خادم Apache
اختبار 2
- تشغيل الخادم IIS/PWS/Cassini
- وضع البرنامج النصي essai1.html في <IIS-DocumentRoot>
- عرض URL http://localhost/essai1.html باستخدام متصفح
2.4.2. صفحة ASP (صفحات الخادم النشطة)
النص البرمجي essai2.asp :
<html>
<head>
<title>essai 1 : une page asp</title>
</head>
<body>
<center>
<h1>Une page asp générée dynamiquement par le serveur PWS</h1>
<h2>Il est <% =time %></h2>
<br>
A chaque fois que vous rafraîchissez la page, l'heure change.
</body>
</html>
ينتج الصفحة التالية:

الاختبار
- تشغيل الخادم IIS/PWS
- وضع البرنامج النصي essai2.asp في <IIS-DocumentRoot>
- اطلب URL http://localhost/essai2.asp باستخدام متصفح
2.4.3. نص برمجي PERL (لغة الاستخراج والإبلاغ العملية)
النص البرمجي essai3.pl:
#!d:\perl\bin\perl.exe
($secondes,$minutes,$heure)=localtime(time);
print <<HTML
Content-type: text/html
<html>
<head>
<title>essai 1 : un script Perl</title>
</head>
<body>
<center>
<h1>Une page générée dynamiquement par un script Perl</h1>
<h2>Il est $heure:$minutes:$secondes</h2>
<br>
A chaque fois que vous rafraîchissez la page, l'heure change.
</body>
</html>
HTML
;
السطر الأول هو مسار الملف القابل للتنفيذ perl.exe. يجب تعديله إذا لزم الأمر. بمجرد تنفيذه بواسطة خادم ويب، ينتج البرنامج النصي الصفحة التالية:

اختبار
- خادم الويب: Apache
- للمعلومات، اعرض ملف التكوين srm.conf أو httpd.conf حسب إصدار Apache في <apache>\confs وابحث عن السطر الذي يشير إلى cgi-bin لمعرفة المجلد <apache-cgi-bin> الذي يجب وضع essai3.pl فيه.
- ضع البرنامج النصي essai3.pl في <apache-cgi-bin>
- اطلب عنوان URL http://localhost/cgi-bin/essai3.pl
تجدر الإشارة إلى أن الحصول على الصفحة perl يستغرق وقتًا أطول من الصفحة asp. ويرجع ذلك إلى أن البرنامج النصي Perl يتم تنفيذه بواسطة مترجم Perl الذي يجب تحميله قبل أن يتمكن من تنفيذ البرنامج النصي. ولا يبقى هذا المترجم في الذاكرة بشكل دائم.
2.4.4. نص برمجي PHP (معالج HyperText)
البرنامج النصي essai4.php
<html>
<head>
<title>essai 4 : une page php</title>
</head>
<body>
<center>
<h1>Une page PHP générée dynamiquement</h1>
<h2>
<?
$maintenant=time();
echo date("j/m/y, h:i:s",$maintenant);
?>
</h2>
<br>
A chaque fois que vous rafraîchissez la page, l'heure change.
</body>
</html>
ينتج البرنامج النصي السابق الصفحة التالية:

الاختبارات
اختبار 1
- راجع ملف التكوين srm.conf أو httpd.conf الخاص بـ Apache في <Apache>\confs
- للعلم، تحقق من أسطر التكوين في php
- تشغيل خادم Apache
- ضع essai4.php في <apache-DocumentRoot>
- اطلب URL http://localhost/essai4.php
Test2
- تشغيل الخادم IIS/PWS
- للعلم، تحقق من تكوين PWS بخصوص php
- وضع essai4.php في <IIS-DocumentRoot>\php
- طلب URL http://localhost/essai4.php
2.4.5. نص برمجي JSP (صفحات خادم Java)
البرنامج النصي heure.jsp
<% //برنامج Java يعرض الوقت %>
<%@ page import="java.util.*" %>
<%
// رمز JAVA لحساب الوقت
Calendar calendrier=Calendar.getInstance();
int heures=calendrier.get(Calendar.HOUR_OF_DAY);
int minutes=calendrier.get(Calendar.MINUTE);
int secondes=calendrier.get(Calendar.SECOND);
// الساعات والدقائق والثواني هي متغيرات عامة
// والتي يمكن استخدامها في الكود HTML
%>
<% // الرمز HTML %>
<html>
<head>
<title>Page JSP affichant l'heure</title>
</head>
<body>
<center>
<h1>Une page JSP générée dynamiquement</h1>
<h2>Il est <%=heures%>:<%=minutes%>:<%=secondes%></h2>
<br>
<h3>A chaque fois que vous rechargez la page, l'heure change</h3>
</body>
</html>
بمجرد تنفيذه بواسطة خادم الويب، ينتج هذا البرنامج النصي الصفحة التالية:

الاختبارات
- ضع البرنامج النصي heure.jsp في <tomcat>\jakarta-tomcat\webapps\examples\jsp (Tomcat 3.x) أو في <tomcat>\webapps\examples\jsp (Tomcat 4.x)
- تشغيل خادم Tomcat
- اطلب URL http://localhost:8080/examples/jsp/heure.jsp
2.4.6. صفحة ASP.NET
النص البرمجي heure1.aspx:
<html>
<head>
<title>Démo asp.net </title>
</head>
<body>
Il est <% =Date.Now.ToString("hh:mm:ss") %>
</body>
</html>
بمجرد تنفيذه بواسطة خادم الويب، ينتج هذا البرنامج النصي الصفحة التالية:

يتطلب هذا الاختبار وجود جهاز يعمل بنظام ويندوز تم تثبيت منصة .NET عليه (انظر الملحق).
- وضع البرنامج النصي heure1.aspx في <IIS-DocumentRoot>
- تشغيل الخادم IIS/CASSINI
- طلب URL http://localhost/heure1.aspx
2.4.7. الخلاصة
أظهرت الأمثلة السابقة أن:
- يمكن إنشاء صفحة HTML ديناميكيًا بواسطة برنامج. وهذا هو جوهر البرمجة على الويب.
- أن اللغات وخوادم الويب المستخدمة يمكن أن تكون متنوعة. نلاحظ حاليًا الاتجاهات الرئيسية التالية:
- الثنائيات Apache/PHP (Windows، Linux) و IIS/PHP (Windows)
- تقنية ASP.NET على منصات Windows التي تربط خادم IIS بلغة .NET (C#، VB.NET، ...)
- تقنية سيرفلتات Java وصفحات JSP التي تعمل مع خوادم مختلفة (Tomcat، Apache، IIS) وعلى منصات مختلفة (Windows، Linux).
2.5. نصوص برمجية على جانب المتصفح
يمكن أن تحتوي صفحة HTML على نصوص برمجية يتم تنفيذها بواسطة المتصفح. هناك العديد من لغات البرمجة النصية على جانب المتصفح. فيما يلي بعض منها:
اللغة | المتصفحات التي يمكن استخدامها |
Vbscript | IE |
Javascript | IE، Netscape |
PerlScript | IE |
Java | IE، Netscape |
لنأخذ بعض الأمثلة.
2.5.1. صفحة ويب تحتوي على برنامج نصي VBScript، على جانب المتصفح
الصفحة vbs1.html
<html>
<head>
<title>essai : une page web avec un script vb</title>
<script language="vbscript">
function reagir
alert "Vous avez cliqué sur le bouton OK"
end function
</script>
</head>
<body>
<center>
<h1>Une page Web avec un script VB</h1>
<table>
<tr>
<td>Cliquez sur le bouton</td>
<td><input type="button" value="OK" name="cmdOK" onclick="reagir"></td>
</tr>
</table>
</body>
</html>
لا تحتوي الصفحة HTML أعلاه على رمز HTML فحسب، بل تحتوي أيضًا على برنامج مخصص للتنفيذ بواسطة المتصفح الذي سيقوم بتحميل هذه الصفحة. الرمز هو كما يلي:
<script language="vbscript">
function reagir
alert "Vous avez cliqué sur le bouton OK"
end function
</script>
تُستخدم العلامات <script></script> لتحديد النصوص البرمجية في الصفحة HTML. يمكن كتابة هذه البرامج النصية بلغات مختلفة، ويشير الخيار language في العلامة <script> إلى اللغة المستخدمة. هنا هي VBScript. لن ندخل في تفاصيل هذه اللغة. يحدد البرنامج النصي أعلاه دالة تسمى réagir تعرض رسالة. متى يتم استدعاء هذه الدالة؟ يوضح لنا ذلك سطر الكود HTML التالي:
تشير السمة onclick إلى اسم الدالة التي سيتم استدعاؤها عندما ينقر المستخدم على الزر OK. عندما يقوم المتصفح بتحميل هذه الصفحة وينقر المستخدم على الزر OK، ستظهر الصفحة التالية:

الاختبارات
المتصفح IE هو الوحيد القادر على تنفيذ البرامج النصية VBScript. يتطلب Netscape ملحقات برمجية للقيام بذلك. يمكن إجراء الاختبارات التالية:
- خادم Apache
- نص برمجي vbs1.html في <apache-DocumentRoot>
-
طلب عنوان URL http://localhost/vbs1.html باستخدام متصفح IE
-
خادم IIS/PWS
- نص برمجي vbs1.html في <pws-DocumentRoot>
- طلب عنوان URL http://localhost/vbs1.html باستخدام متصفح IE
صفحة ويب تحتوي على نص برمجي جافا سكريبت، من جانب المتصفح
La page : js1.html
<html>
<head>
<title>essai 4 : une page web avec un script Javascript</title>
<script language="javascript">
function reagir(){
alert ("Vous avez cliqué sur le bouton OK");
}
</script>
</head>
<body>
<center>
<h1>Une page Web avec un script Javascript</h1>
<table>
<tr>
<td>Cliquez sur le bouton</td>
<td><input type="button" value="OK" name="cmdOK" onclick="reagir()"></td>
</tr>
</table>
</body>
</html>
لدينا هنا شيء مشابه للصفحة السابقة، باستثناء أننا استبدلنا لغة VBScript بلغة جافا سكريبت. تتميز هذه اللغة بأنها مقبولة من قبل متصفحي IE و Netscape. ويؤدي تنفيذها إلى نفس النتائج:

الاختبارات
- خادم Apache
- البرنامج النصي js1.html في <apache-DocumentRoot>
-
طلب عنوان URL http://localhost/js1.html باستخدام متصفح IE أو Netscape
-
خادم IIS/PWS
- البرنامج النصي js1.html في <pws-DocumentRoot>
- طلب عنوان URL http://localhost/js1.html باستخدام متصفح IE أو Netscape
2.6. التبادلات بين العميل والخادم
لنعد إلى مخططنا الأولي الذي يوضح العناصر الفاعلة في تطبيق ويب:

جهاز الخادم
نحن مهتمون هنا بالتبادل بين جهاز العميل وجهاز الخادم. يتم هذا التبادل عبر شبكة، ومن الجيد تذكير البنية العامة للتبادل بين جهازين بعيدين.
2.6.1. نموذج OSI
يصف نموذج الشبكة المفتوحة المسمى OSI (نموذج مرجعي لربط الأنظمة المفتوحة) الذي حددته المنظمة الدولية للمعايير (ISO) شبكةً مثاليةً يمكن فيها تمثيل الاتصال بين الأجهزة بنموذج مكون من سبع طبقات:

تتلقى كل طبقة خدمات من الطبقة السفلية وتقدم خدماتها إلى الطبقة العليا. لنفترض أن تطبيقين موجودين على جهازين مختلفين A و B يرغبان في التواصل: فهما يفعلان ذلك على مستوى الطبقة Application. ولا يحتاجان إلى معرفة كل تفاصيل عمل الشبكة: فكل تطبيق يمرر المعلومات التي يرغب في إرسالها إلى الطبقة التي تليه: الطبقة Présentation. وبالتالي، لا يحتاج التطبيق سوى إلى معرفة قواعد التفاعل مع الطبقة Présentation. وبمجرد وصول المعلومات إلى الطبقة Présentation، تنتقل وفقًا لقواعد أخرى إلى الطبقة Session وهكذا دواليك، حتى تصل المعلومات إلى الوسيط المادي وتُنقل فعليًا إلى الجهاز المقصود. وهناك، ستخضع للمعالجة العكسية لتلك التي خضعت لها على الجهاز المرسل.
في كل طبقة، تقوم العملية المرسلة المكلفة بإرسال المعلومات بإرسالها إلى عملية مستقبلة على الجهاز الآخر الذي ينتمي إلى نفس الطبقة. وتقوم بذلك وفقًا لقواعد معينة تسمى بروتوكول الطبقة. وبالتالي، يكون مخطط الاتصال النهائي كما يلي:

دور الطبقات المختلفة هو كما يلي:
تضمن نقل البتات عبر وسيط مادي. يوجد في هذه الطبقة معدات طرفية لمعالجة البيانات (E.T.T.D.) مثل المحطة الطرفية أو الكمبيوتر، بالإضافة إلى معدات إنهاء دوائر البيانات (E.T.C.D.) مثل المُعدِّل/المُفكِّك، والمُضاعِف، والمُركِّز. النقاط المهمة في هذا المستوى هي: . اختيار ترميز المعلومات (تناظري أو رقمي) . اختيار طريقة الإرسال (متزامن أو غير متزامن). | |
يخفي الخصائص الفيزيائية للطبقة الفيزيائية. يكتشف أخطاء الإرسال ويصححها. | |
يدير المسار الذي يجب أن تتبعه المعلومات المرسلة عبر الشبكة. ويُطلق على ذلك اسم routage: تحديد المسار الذي يجب أن تتبعه المعلومات حتى تصل إلى مستلمها. | |
يسمح بالاتصال بين تطبيقين في حين أن الطبقات السابقة كانت تسمح فقط بالاتصال بين الأجهزة. قد تكون إحدى الخدمات التي توفرها هذه الطبقة هي التعدد: يمكن لطبقة النقل استخدام نفس اتصال الشبكة (من جهاز إلى جهاز) لنقل المعلومات الخاصة بعدة تطبيقات. | |
نجد في هذه الطبقة خدمات تسمح لتطبيق ما بفتح جلسة عمل والحفاظ عليها على جهاز بعيد. | |
وتهدف هذه الطبقة إلى توحيد عرض البيانات على الأجهزة المختلفة. وبالتالي، فإن البيانات الواردة من جهاز A سيتم "تغليفها" بواسطة طبقة Présentation الخاصة بجهاز A، وفقًا لتنسيق قياسي قبل إرسالها عبر الشبكة. وعند وصولها إلى الطبقة Présentation للجهاز المستلم B الذي سيتعرف عليها بفضل تنسيقها القياسي، سيتم تزيينها بطريقة أخرى حتى يتعرف عليها تطبيق الجهاز B. | |
في هذه المرحلة، نجد التطبيقات التي عادةً ما تكون قريبة من المستخدم مثل البريد الإلكتروني أو نقل الملفات. |
2.6.2. الطراز TCP/IP
يعد النموذج OSI نموذجًا مثاليًا. وتقترب مجموعة البروتوكولات TCP/IP منه بالشكل التالي:

- تؤدي واجهة الشبكة (بطاقة الشبكة في الكمبيوتر) وظائف الطبقتين 1 و 2 من النموذج OSI
- تؤدي الطبقة IP (بروتوكول الإنترنت) وظائف الطبقة 3 (الشبكة)
- الطبقة TCP (بروتوكول التحكم في النقل) أو UDP (بروتوكول مخطط بيانات المستخدم) تؤدي وظائف الطبقة 4 (النقل). يضمن بروتوكول TCP وصول حزم البيانات المتبادلة بين الأجهزة إلى وجهتها. إذا لم يكن الأمر كذلك، فإنه يعيد الحزم التي ضلت طريقها. لا يقوم بروتوكول UDP بهذه المهمة، وبالتالي يقع على عاتق مطور التطبيقات القيام بها. ولهذا السبب، على الإنترنت الذي لا يعتبر شبكة موثوقة بنسبة 100٪، فإن بروتوكول TCP هو الأكثر استخدامًا. ونسميها عندئذ شبكة TCP-IP.
- تغطي طبقة التطبيق وظائف المستويات من 5 إلى 7 في نموذج OSI.
توجد تطبيقات الويب في الطبقة Application، وبالتالي فهي تعتمد على بروتوكولات TCP-IP. تتبادل طبقات Application في أجهزة العملاء والخادم الرسائل التي يتم تكليف الطبقات من 1 إلى 4 في النموذج بتوجيهها إلى وجهتها. لكي تتفاهم، يجب أن "تتحدث" طبقات التطبيق في الجهازين نفس اللغة أو البروتوكول. يُسمى بروتوكول تطبيقات الويب HTTP (بروتوكول النقل HyperText). وهو بروتوكول نصي، c.a.d. حيث تتبادل الأجهزة أسطر نصية عبر الشبكة للتواصل. هذه التبادلات موحدة، c.a.d. حيث يتوفر للعميل عدد معين من الرسائل للإشارة بالضبط إلى ما يريده من الخادم، كما يتوفر للخادم أيضًا عدد معين من الرسائل لإعطاء العميل إجابته. يتخذ تبادل الرسائل هذا الشكل التالي:

العميل --> الخادم
عندما يرسل العميل طلبه إلى خادم الويب، فإنه يرسل
- سطور نصية بتنسيق HTTP للإشارة إلى ما يريده
- سطر فارغ
- وثيقة اختيارية
الخادم --> العميل
عندما يرد الخادم على العميل، فإنه يرسل
- سطور نصية بتنسيق HTTP للإشارة إلى ما يرسله
- سطر فارغ
- اختياريًا مستند
وبالتالي، فإن التبادلات تتخذ نفس الشكل في كلا الاتجاهين. في كلتا الحالتين، قد يتم إرسال مستند حتى وإن كان من النادر أن يرسل العميل مستندًا إلى الخادم. لكن بروتوكول HTTP ينص على ذلك. وهذا ما يسمح، على سبيل المثال، لمشتركي مزود خدمة الإنترنت بتنزيل مستندات متنوعة على مواقعهم الشخصية المستضافة لدى هذا المزود. يمكن أن تكون المستندات المتبادلة أي نوع. لنأخذ متصفحًا يطلب صفحة ويب تحتوي على صور:
- يتصل المتصفح بخادم الويب ويطلب الصفحة التي يريدها. يتم تعيين الموارد المطلوبة بشكل فريد بواسطة URL (محدد موقع الموارد الموحد). لا يرسل المتصفح سوى رؤوس HTTP ولا يرسل أي مستند.
- يرد عليه الخادم. يرسل أولاً رؤوس HTTP تشير إلى نوع الرد الذي يرسله. قد يكون هذا خطأً إذا كانت الصفحة المطلوبة غير موجودة. إذا كانت الصفحة موجودة، سيذكر الخادم في رؤوس HTTP لرده أنه سيقوم بعد ذلك بإرسال مستند HTML (لغة ترميز HyperText). هذا المستند عبارة عن سلسلة من أسطر النص بتنسيق HTML. يحتوي نص HTML على علامات (علامات) تعطي للمتصفح إرشادات حول كيفية عرض النص.
- يعرف العميل من خلال رؤوس HTTP للخادم أنه سيتلقى مستند HTML. سيقوم بتحليل هذا المستند وربما يلاحظ أنه يحتوي على مراجع لصور. هذه الصور غير موجودة في المستند HTML. لذلك يقوم بإرسال طلب جديد إلى نفس خادم الويب لطلب الصورة الأولى التي يحتاجها. هذا الطلب مطابق للطلب الذي تم إرساله في الخطوة 1، باستثناء أن المورد المطلوب مختلف. سيقوم الخادم بمعالجة هذا الطلب عن طريق إرسال الصورة المطلوبة إلى عميله. هذه المرة، في رده، ستوضح رؤوس HTTP أن المستند المرسل هو صورة وليس مستند HTML.
- يسترد العميل الصورة المرسلة. ستتكرر الخطوتان 3 و 4 حتى يحصل العميل (متصفح بشكل عام) على جميع المستندات التي تسمح له بعرض الصفحة بالكامل.
2.6.3. بروتوكول HTTP
لنكتشف بروتوكول HTTP من خلال أمثلة. ما الذي يتبادله المتصفح وخادم الويب؟
2.6.3.1. استجابة خادم HTTP
سنكتشف هنا كيف يستجيب خادم الويب لطلبات عملائه. خدمة الويب أو خدمة HTTP هي خدمة TCP-IP تعمل عادةً على المنفذ 80. وقد تعمل على منفذ آخر. في هذه الحالة، سيضطر متصفح العميل إلى تحديد هذا المنفذ في طلب URL الذي يقدمه. تتخذ URL الشكل العام التالي:
مع
بروتوكول | http لخدمة الويب. يمكن للمتصفح أيضًا أن يعمل كعميل لخدمات ftp و news و telnet، ... |
الجهاز | اسم الجهاز الذي تعمل عليه خدمة الويب |
المنفذ | منفذ خدمة الويب. إذا كان 80، يمكن حذف رقم المنفذ. وهذا هو الحال الأكثر شيوعًا |
المسار | المسار الذي يشير إلى المورد المطلوب |
المعلومات | معلومات إضافية تُقدم إلى الخادم لتوضيح طلب العميل |
ماذا يفعل المتصفح عندما يطلب المستخدم تحميل ملف URL؟
- يفتح اتصالاً TCP-IP مع الجهاز والمنفذ المحددين في الجزء machine[:port] من URL. إن فتح اتصال TCP-IP يعني إنشاء "قناة" اتصال بين جهازين. وبمجرد إنشاء هذه القناة، ستمر جميع المعلومات المتبادلة بين الجهازين عبرها. لا يتضمن إنشاء هذا القناة TCP-IP بروتوكول الويب HTTP بعد.
- بعد إنشاء القناة TCP-IP، سيقوم العميل بتوجيه طلبه إلى خادم الويب، وسيفعل ذلك عن طريق إرسال أسطر نصية (أوامر) بتنسيق HTTP. سيقوم بإرسال جزء المسار/المعلومات من URL إلى الخادم
- سيرد عليه الخادم بنفس الطريقة وفي نفس الأنبوب
- سيتخذ أحد الشريكين قرار إغلاق القناة. وهذا يعتمد على بروتوكول HTTP المستخدم. مع بروتوكول HTTP 1.0، يغلق الخادم الاتصال بعد كل رد من ردوده. وهذا يجبر العميل الذي يحتاج إلى إرسال عدة طلبات للحصول على المستندات المختلفة التي تشكل صفحة ويب على فتح اتصال جديد مع كل طلب، وهو ما يترتب عليه تكلفة. مع بروتوكول HTTP/1.1، يمكن للعميل أن يطلب من الخادم إبقاء الاتصال مفتوحًا حتى يطلب منه إغلاقه. وبالتالي، يمكنه استرداد جميع المستندات الخاصة بصفحة ويب عبر اتصال واحد وإغلاق الاتصال بنفسه بمجرد الحصول على آخر مستند. سيكتشف الخادم هذا الإغلاق ويقوم هو أيضًا بإغلاق الاتصال.
لاكتشاف التبادلات بين عميل وخادم ويب، سنستخدم أداة تسمى curl. Curl هو تطبيق DOS يسمح بأن تكون عميلاً لخدمات الإنترنت التي تدعم بروتوكولات مختلفة (HTTP، FTP، TELNET، GOPHER، ...). تتوفر curl على http://curl.haxx.se/. يفضل هنا تنزيل إصدار Windows win32-nossl، حيث يتطلب إصدار win32-ssl ملفات dll إضافية غير متوفرة في حزمة curl. تحتوي هذه الحزمة على مجموعة من الملفات التي يكفي فك ضغطها في مجلد سنسميه من الآن فصاعدًا <curl>. يحتوي هذا المجلد على ملف قابل للتنفيذ يسمى [curl.exe]. سيكون هذا هو عميلنا لاستعلام خوادم الويب. نفتح نافذة DOS وننتقل إلى المجلد <curl>:
dos>dir curl.exe
22/03/2004 13:29 299 008 curl.exe
E:\curl2>curl
curl: try 'curl --help' for more information
dos>curl --help | more
Usage: curl [options...] <url>
Options: (H) means HTTP/HTTPS only, (F) means FTP only
-a/--append Append to target file when uploading (F)
-A/--user-agent <string> User-Agent to send to server (H)
--anyauth Tell curl to choose authentication method (H)
-b/--cookie <name=string/file> Cookie string or file to read cookies from (H)
--basic Enable HTTP Basic Authentication (H)
-B/--use-ascii Use ASCII/text transfer
-c/--cookie-jar <file> Write cookies to this file after operation (H)
....
لنستخدم هذا التطبيق لاستعلام خادم ويب واكتشاف التبادلات بين العميل والخادم. سنكون في الحالة التالية:

يمكن أن يكون خادم الويب أي خادم. نسعى هنا لاكتشاف التبادلات التي ستحدث بين عميل الويب curl وخادم الويب. في السابق، أنشأنا الصفحة الثابتة التالية HTML:
<html>
<head>
<title>essai 1 : une page statique</title>
</head>
<body>
<center>
<h1>Une page statique...</h1>
</body>
</html>
التي نعرضها في متصفح:

نرى أن URL المطلوب هو: http://localhost/aspnet/chap1/statique1.html. وبالتالي، فإن جهاز خدمة الويب هو localhost (=جهاز محلي) والمنفذ هو 80. إذا طلبنا عرض النص HTML لهذه الصفحة الويب (عرض/المصدر)، فسنجد النص HTML الذي تم إنشاؤه في البداية:

الآن دعونا نستخدم عميلنا CURL لطلب نفس URL:
dos>curl http://localhost/aspnet/chap1/statique1.html
<html>
<head>
<title>essai 1 : une page statique</title>
</head>
<body>
<center>
<h1>Une page statique...</h1>
</body>
</html>
نرى أن خادم الويب أرسل إليه مجموعة من أسطر النص التي تمثل الرمز HTML للصفحة المطلوبة. ذكرنا سابقًا أن استجابة خادم الويب تأتي بالشكل التالي:

ولكن هنا، لم نرَ الرؤوس HTTP. وذلك لأن [curl] لا يعرضها بشكل افتراضي. تسمح الخيار --include بعرضها:
E:\curl2>curl --include http://localhost/aspnet/chap1/statique1.html
HTTP/1.1 200 OK
Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
Date: Mon, 22 Mar 2004 16:51:00 GMT
X-AspNet-Version: 1.1.4322
Cache-Control: public
ETag: "1C4102CEE8C6400:1C4102CFBBE2250"
Content-Type: text/html
Content-Length: 161
Connection: Close
<html>
<head>
<title>essai 1 : une page statique</title>
</head>
<body>
<center>
<h1>Une page statique...</h1>
</body>
</html>
أرسل الخادم بالفعل سلسلة من الرؤوس HTTP متبوعة بسطر فارغ:
HTTP/1.1 200 OK
Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
Date: Mon, 22 Mar 2004 16:51:00 GMT
X-AspNet-Version: 1.1.4322
Cache-Control: public
ETag: "1C4102CEE8C6400:1C4102CFBBE2250"
Content-Type: text/html
Content-Length: 161
Connection: Close
يقول الخادم
| |
يحدد الخادم هويته. هنا هو خادم Cassini | |
تاريخ/وقت الرد | |
رأس خاص بخادم Cassini | |
يقدم إرشادات للعميل حول إمكانية تخزين الرد المرسل إليه في ذاكرة التخزين المؤقت. يشير السمة [public] إلى أنه يمكن للعميل تخزين الصفحة في ذاكرة التخزين المؤقت. أما السمة [no-cache] فستشير إلى أنه لا يجب على العميل تخزين الصفحة في ذاكرة التخزين المؤقت. | |
... | |
يخبر الخادم أنه سيرسل نصًا (text) بتنسيق HTML (html). | |
عدد البايتات في المستند الذي سيتم إرساله بعد الرؤوس HTTP. هذا الرقم هو في الواقع حجم الملف بالبايت essai1.html: | |
يقول الخادم أنه سيغلق الاتصال بمجرد إرسال المستند |
يتلقى العميل هذه الرؤوس HTTP ويعرف الآن أنه سيتلقى 161 بايت تمثل مستندًا HTML. يرسل الخادم هذه الـ 161 بايت مباشرة بعد السطر الفارغ الذي يشير إلى نهاية الرؤوس HTTP:
<html>
<head>
<title>essai 1 : une page statique</title>
</head>
<body>
<center>
<h1>Une page statique...</h1>
</body>
</html>
يمكننا هنا التعرف على الملف HTML الذي تم إنشاؤه في البداية. إذا كان عميلنا متصفحًا، فسيقوم بعد استلام هذه الأسطر النصية بتفسيرها لعرض الصفحة التالية للمستخدم على لوحة المفاتيح:

لنستخدم مرة أخرى عميلنا [curl] لطلب المورد نفسه، ولكن هذه المرة بطلب رؤوس الاستجابة فقط:
dos>curl --head http://localhost/aspnet/chap1/statique1.html
HTTP/1.1 200 OK
Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
Date: Tue, 23 Mar 2004 07:11:54 GMT
Cache-Control: public
ETag: "1C410A504D60680:1C410A58621AD3E"
Content-Type: text/html
Content-Length: 161
Connection: Close
نحصل على نفس النتيجة السابقة بدون المستند HTML. الآن لنطلب صورة باستخدام متصفح وكذلك باستخدام العميل العام TCP. أولاً باستخدام متصفح:

يبلغ حجم الملف univ01.gif 4052 بايت:
لنستخدم الآن عميل [curl]:
dos>curl --head http://localhost/aspnet/chap1/univ01.gif
HTTP/1.1 200 OK
Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
Date: Tue, 23 Mar 2004 07:18:44 GMT
Cache-Control: public
ETag: "1C410A6795D7500:1C410A6868B1476"
Content-Type: image/gif
Content-Length: 4052
Connection: Close
تجدر الإشارة إلى النقاط التالية في دورة الطلب والاستجابة المذكورة أعلاه:
| |
| |
|
2.6.3.2. طلب عميل HTTP
الآن، لنطرح السؤال التالي: إذا أردنا كتابة برنامج "يتواصل" مع خادم ويب، ما هي الأوامر التي يجب أن يرسلها إلى خادم الويب للحصول على مورد معين؟ لقد رأينا في الأمثلة السابقة ما يتلقاه العميل ولكن لم نر ما يرسله العميل. سنستخدم خيار [--verbose] في curl لنرى أيضًا ما يرسله العميل إلى الخادم. لنبدأ بطلب الصفحة الثابتة:
dos>curl --verbose http://localhost/aspnet/chap1/statique1.html
* About to connect() to localhost:80
* Connected to portable1_tahe (127.0.0.1) port 80
> GET /aspnet/chap1/statique1.html HTTP/1.1
User-Agent: curl/7.10.8 (win32) libcurl/7.10.8 OpenSSL/0.9.7a zlib/1.1.4
Host: localhost
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
< HTTP/1.1 200 OK
< Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
< Date: Tue, 23 Mar 2004 07:37:06 GMT
< Cache-Control: public
< ETag: "1C410A504D60680:1C410A58621AD3E"
< Content-Type: text/html
< Content-Length: 161
< Connection: Close
<html>
<head>
<title>essai 1 : une page statique</title>
</head>
<body>
<center>
<h1>Une page statique...</h1>
</body>
</html>
* Closing connection #0
أولاً، يقوم العميل [curl] بإنشاء اتصال TCP/IP مع المنفذ 80 لجهاز localhost (=127.0.0.1)
بمجرد إنشاء الاتصال، يرسل طلبه HTTP. وهو عبارة عن سلسلة من أسطر النص تنتهي بسطر فارغ:
GET /aspnet/chap1/statique1.html HTTP/1.1
User-Agent: curl/7.10.8 (win32) libcurl/7.10.8 OpenSSL/0.9.7a zlib/1.1.4
Host: localhost
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
الطلب HTTP من عميل ويب له وظيفتان:
- تحديد المورد المطلوب. وهذا هو دور السطر الأول GET
- تقديم معلومات عن العميل الذي يقوم بالطلب حتى يتمكن الخادم من تكييف استجابته مع هذا النوع المحدد من العملاء.
معنى الأسطر المرسلة أعلاه من قبل العميل [curl] هو كما يلي:
لطلب مورد معين وفقًا لإصدار معين من البروتوكول HTTP. يرسل الخادم استجابة بتنسيق HTTP متبوعة بسطر فارغ ثم المورد المطلوب | |
للإشارة إلى هوية العميل | |
لتحديد (بروتوكول HTTP 1.1) الجهاز والمنفذ الخاص بخادم الويب الذي تم الاستعلام عنه | |
هنا لتوضيح أن العميل لا يدير ذاكرة التخزين المؤقت. | |
أنواع MIME تحدد أنواع الملفات التي يستطيع العميل إدارتها |
لنعيد العملية باستخدام الخيار --head من [curl]:
dos>curl --verbose --head --output reponse.txt http://localhost/aspnet/chap1/statique1.html
* About to connect() to localhost:80
* Connected to portable1_tahe (127.0.0.1) port 80
> HEAD /aspnet/chap1/statique1.html HTTP/1.1
User-Agent: curl/7.10.8 (win32) libcurl/7.10.8 OpenSSL/0.9.7a zlib/1.1.4
Host: localhost
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
< HTTP/1.1 200 OK
< Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
< Date: Tue, 23 Mar 2004 07:54:22 GMT
< Cache-Control: public
< ETag: "1C410A504D60680:1C410A58621AD3E"
< Content-Type: text/html
< Content-Length: 161
< Connection: Close
نحن نركز فقط على الرؤوس HTTP المرسلة من قبل العميل:
HEAD /aspnet/chap1/statique1.html HTTP/1.1
User-Agent: curl/7.10.8 (win32) libcurl/7.10.8 OpenSSL/0.9.7a zlib/1.1.4
Host: localhost
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
لم يتغير سوى الأمر الذي يطلب المورد. بدلاً من الأمر GET، لدينا الآن الأمر HEAD. يطلب هذا الأمر أن تقتصر استجابة الخادم على الرؤوس HTTP وألا يرسل المورد المطلوب. لا تعرض لقطة الشاشة أعلاه الرؤوس HTTP المستلمة. تم وضع هذه الرؤوس في ملف بسبب الخيار [--output reponse.txt] في الأمر [curl]:
dos>more reponse.txt
HTTP/1.1 200 OK
Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
Date: Tue, 23 Mar 2004 07:54:22 GMT
Cache-Control: public
ETag: "1C410A504D60680:1C410A58621AD3E"
Content-Type: text/html
Content-Length: 161
Connection: Close
2.6.4. الخلاصة
لقد اكتشفنا بنية طلب عميل الويب وبنية الرد الذي يقدمه له خادم الويب من خلال بعض الأمثلة. يتم الحوار باستخدام بروتوكول HTTP، وهو مجموعة من الأوامر بتنسيق نصي يتم تبادلها بين الطرفين. يتبع طلب العميل ورد الخادم نفس البنية التالية:

في حالة طلب (يُسمى غالبًا استعلام) من العميل، غالبًا ما يكون الجزء [Document] غائبًا. ومع ذلك، يمكن للعميل إرسال مستند إلى الخادم. ويقوم بذلك باستخدام أمر يُسمى PUT. الأمران الشائعان لطلب مورد هما GET و POST. وسيتم عرض هذا الأخير لاحقًا. يسمح الأمر HEAD بطلب الرؤوس فقط HTTP. الأمران GET و POST هما الأكثر استخدامًا من قبل عملاء الويب من نوع المتصفح.
بناءً على طلب العميل، يرسل الخادم استجابة لها نفس البنية. يتم إرسال المورد المطلوب في الجزء [Document] ما لم يكن الأمر المرسَل من العميل هو HEAD، وفي هذه الحالة يتم إرسال رؤوس HTTP فقط.
2.7. لغة HTML
يمكن لمتصفح الويب عرض مستندات متنوعة، وأكثرها شيوعًا هو المستند HTML (لغة ترميز HyperText). وهو عبارة عن نص منسق بعلامات على شكل <balise>texte</balise>. وبالتالي، فإن النص <B>important</B> سيعرض النص المهم بخط عريض. توجد علامات منفردة مثل العلامة <hr> التي تعرض خطًا أفقيًا. لن نستعرض العلامات التي يمكن العثور عليها في نص HTML. هناك العديد من برامج WYSIWYG التي تسمح بإنشاء صفحة ويب دون كتابة سطر واحد من كود HTML. تولد هذه الأدوات تلقائيًا كود HTML لتخطيط تم إنشاؤه باستخدام الماوس وعناصر تحكم محددة مسبقًا. وبالتالي، يمكن إدراج (باستخدام الماوس) جدول في الصفحة ثم الاطلاع على كود HTML الذي أنشأه البرنامج لاكتشاف العلامات التي يجب استخدامها لتعريف جدول في صفحة ويب. الأمر ليس أكثر تعقيدًا من ذلك. من ناحية أخرى، فإن معرفة لغة HTML أمر لا غنى عنه لأن تطبيقات الويب الديناميكية يجب أن تولد بنفسها كود HTML لإرساله إلى عملاء الويب. يتم إنشاء هذا الكود بواسطة البرنامج ويجب بالطبع معرفة ما يجب إنشاؤه حتى يحصل العميل على صفحة الويب التي يريدها.
باختصار، ليس هناك حاجة لمعرفة لغة HTML بالكامل لبدء البرمجة على الويب. ومع ذلك، فإن هذه المعرفة ضرورية ويمكن اكتسابها من خلال استخدام برامج إنشاء صفحات الويب مثل Word وFrontPage وDreamWeaver وعشرات البرامج الأخرى. هناك طريقة أخرى لاكتشاف خفايا لغة HTML وهي تصفح الويب وعرض الكود المصدري للصفحات التي تتميز بخصائص مثيرة للاهتمام وغير معروفة لك بعد.
2.7.1. مثال
لنأخذ المثال التالي، الذي تم إنشاؤه باستخدام FrontPage Express، وهي أداة مجانية مرفقة مع Internet Explorer. تم تنقيح الكود الذي أنشأه Frontpage هنا. يعرض هذا المثال بعض العناصر التي يمكن العثور عليها في مستند ويب مثل:
- جدول
- صورة
- رابط

يكون شكل مستند HTML بشكل عام كما يلي:
يتم تأطير الوثيقة بأكملها بعلامات <html>...</html>. وهي تتكون من جزأين:
- <head>...</head>: هذا هو الجزء غير القابل للعرض من المستند. وهو يوفر معلومات للمتصفح الذي سيقوم بعرض المستند. غالبًا ما نجد فيه العلامة <title>...</title> التي تحدد النص الذي سيتم عرضه في شريط عنوان المتصفح. ويمكن أن نجد فيه علامات أخرى، لا سيما العلامات التي تحدد الكلمات المفتاحية للمستند، وهي الكلمات المفتاحية التي تستخدمها محركات البحث لاحقًا. يمكن أيضًا العثور في هذا الجزء على نصوص برمجية، مكتوبة غالبًا بلغة جافا سكريبت أو في بي سكريبت، والتي سيتم تنفيذها بواسطة المتصفح.
- <body attributs>...</body>: هذا هو الجزء الذي سيعرضه المتصفح. تشير العلامات HTML الموجودة في هذا الجزء إلى المتصفح الشكل المرئي "المطلوب" للوثيقة. سيقوم كل متصفح بتفسير هذه العلامات بطريقته الخاصة. وبالتالي، يمكن لمتصفحين مختلفين عرض نفس المستند على الويب بشكل مختلف. وهذا عادةً ما يمثل أحد التحديات التي يواجهها مصممو الويب.
الرمز HTML لوثيقتنا النموذجية هو التالي:
<html>
<head>
<title>balises</title>
</head>
<body background="/images/standard.jpg">
<center>
<h1>Les balises HTML</h1>
<hr>
</center>
<table border="1">
<tr>
<td>cellule(1,1)</td>
<td valign="middle" align="center" width="150">cellule(1,2)</td>
<td>cellule(1,3)</td>
</tr>
<tr>
<td>cellule(2,1)</td>
<td>cellule(2,2)</td>
<td>cellule(2,3</td>
</tr>
</table>
<table border="0">
<tr>
<td>Une image</td>
<td><img border="0" src="/images/univ01.gif" width="80" height="95"></td>
</tr>
<tr>
<td>le site de l'ISTIA</td>
<td><a href="http://istia.univ-angers.fr">ici</a></td>
</tr>
</table>
</body>
</html>
تم إبراز النقاط التي تهمنا فقط في الكود:
العناصر | العلامات والأمثلة HTML |
<title>balises</title> balises سيظهر في شريط عنوان المتصفح الذي سيعرض المستند | |
<hr>: يعرض خطًا أفقيًا | |
<سمات الجدول>....</table>: لتعريف الجدول <tr attributes>...</tr>: لتعريف سطر <td سمات>...</td>: لتعريف خلية أمثلة: <table border="1">...</table>: تحدد السمة border سماكة حدود الجدول <td valign="middle" align="center" width="150">خلية(1,2)</td>: تحدد خلية سيكون محتواها هو الخلية(1,2). سيتم توسيط هذا المحتوى عموديًا (valign="middle") وأفقيًا (align="center"). سيكون عرض الخلية 150 بكسل (width="150") | |
<img border="0" src="/images/univ01.gif" width="80" height="95">: تحدد صورة بدون حدود (border="0")، بارتفاع 95 بكسل (height="95")، وعرضها 80 بكسل (width="80") وملفها المصدر هو /images/univ01.gif على خادم الويب (src="/images/univ01.gif"). يوجد هذا الرابط في مستند ويب تم الحصول عليه باستخدام URL http://localhost:81/html/balises.htm. كما سيطلب المتصفح URL http://localhost:81/images/univ01.gif للحصول على الصورة المشار إليها هنا. | |
<a href="http://istia.univ-angers.fr">هنا</a>: يجعل النص ici بمثابة رابط إلى URL http://istia.univ-angers.fr. | |
<body background="/images/standard.jpg">: يشير إلى أن الصورة التي يجب أن تستخدم كخلفية للصفحة موجودة في /images/standard.jpg على خادم الويب. في سياق مثالنا، سيطلب المتصفح http://localhost:81/images/standard.jpg للحصول على صورة الخلفية هذه. |
نرى في هذا المثال البسيط أنه لإنشاء المستند بالكامل، يجب على المتصفح إرسال ثلاث طلبات إلى الخادم:
- http://localhost:81/html/balises.htm للحصول على مصدر HTML للوثيقة
- http://localhost:81/images/univ01.gif للحصول على الصورة univ01.gif
- http://localhost:81/images/standard.jpg للحصول على صورة الخلفية standard.jpg
يقدم المثال التالي نموذج ويب تم إنشاؤه أيضًا باستخدام FrontPage.

الرمز HTML الذي تم إنشاؤه بواسطة FrontPage وتم تنقيحه قليلاً هو التالي:
<html>
<head>
<title>balises</title>
<script language="JavaScript">
function effacer(){
alert("Vous avez cliqué sur le bouton Effacer");
}//مسح
</script>
</head>
<body background="/images/standard.jpg">
<form method="POST" >
<table border="0">
<tr>
<td>Etes-vous marié(e)</td>
<td>
<input type="radio" value="Oui" name="R1">Oui
<input type="radio" name="R1" value="non" checked>Non
</td>
</tr>
<tr>
<td>Cases à cocher</td>
<td>
<input type="checkbox" name="C1" value="un">1
<input type="checkbox" name="C2" value="deux" checked>2
<input type="checkbox" name="C3" value="trois">3
</td>
</tr>
<tr>
<td>Champ de saisie</td>
<td>
<input type="text" name="txtSaisie" size="20" value="qqs mots">
</td>
</tr>
<tr>
<td>Mot de passe</td>
<td>
<input type="password" name="txtMdp" size="20" value="unMotDePasse">
</td>
</tr>
<tr>
<td>Boîte de saisie</td>
<td>
<textarea rows="2" name="areaSaisie" cols="20">
ligne1
ligne2
ligne3
</textarea>
</td>
</tr>
<tr>
<td>combo</td>
<td>
<select size="1" name="cmbValeurs">
<option>choix1</option>
<option selected>choix2</option>
<option>choix3</option>
</select>
</td>
</tr>
<tr>
<td>liste à choix simple</td>
<td>
<select size="3" name="lst1">
<option selected>liste1</option>
<option>liste2</option>
<option>liste3</option>
<option>liste4</option>
<option>liste5</option>
</select>
</td>
</tr>
<tr>
<td>liste à choix multiple</td>
<td>
<select size="3" name="lst2" multiple>
<option>liste1</option>
<option>liste2</option>
<option selected>liste3</option>
<option>liste4</option>
<option>liste5</option>
</select>
</td>
</tr>
<tr>
<td>bouton</td>
<td>
<input type="button" value="Effacer" name="cmdEffacer" onclick="effacer()">
</td>
</tr>
<tr>
<td>envoyer</td>
<td>
<input type="submit" value="Envoyer" name="cmdRenvoyer">
</td>
</tr>
<tr>
<td>rétablir</td>
<td>
<input type="reset" value="Rétablir" name="cmdRétablir">
</td>
</tr>
</table>
<input type="hidden" name="secret" value="uneValeur">
</form>
</body>
</html>
الارتباط بين الفحص البصري <--> العلامة HTML هو التالي:
التحكم | العلامة HTML |
<form method="POST" > | |
<input type="text" name="txtSaisie" size="20" value="بضع كلمات"> | |
<input type="password" name="txtMdp" size="20" value="unMotDePasse"> | |
<textarea rows="2" name="areaSaisie" cols="20"> السطر 1 السطر 2 السطر 3 </textarea> | |
<input type="radio" value="نعم" name="R1">نعم <input type="radio" name="R1" value="لا" checked>لا | |
<input type="checkbox" name="C1" value="واحد">1 <input type="checkbox" name="C2" value="اثنان" checked>2 <input type="checkbox" name="C3" value="ثلاثة">3 | |
<select size="1" name="cmbValeurs"> <option>الخيار 1</option> <option selected>الخيار 2</option> <option>الخيار 3</option> </select> | |
<select size="3" name="lst1"> <option selected>القائمة 1</option> <option>القائمة 2</option> <option>القائمة 3</option> <option>القائمة 4</option> <option>القائمة 5</option> </select> | |
<select size="3" name="lst2" multiple> <option>القائمة 1</option> <option>القائمة 2</option> <option selected>القائمة 3</option> <option>القائمة 4</option> <option>القائمة 5</option> </select> | |
<input type="submit" value="إرسال" name="cmdRenvoyer"> | |
<input type="reset" value="إعادة تعيين" name="cmdRétablir"> | |
<input type="button" value="مسح" name="cmdEffacer" onclick="effacer()"> |
لنستعرض هذه العناصر المختلفة.
2.7.1.1. النموذج
<form method="POST" > |
<form name="..." method="..." action="...">...</form> | |
name="frmexemple": اسم النموذج method="..." : الطريقة التي يستخدمها المتصفح لإرسال القيم التي تم جمعها في النموذج إلى خادم الويب action="..." : URL التي سيتم إرسال القيم التي تم جمعها في النموذج إليها. يُحاط النموذج الإلكتروني بعلامات <form>...</form>. يمكن أن يكون للنموذج اسم (name="xx"). وينطبق ذلك على جميع عناصر التحكم الموجودة في النموذج. ويكون هذا الاسم مفيدًا إذا كان المستند الإلكتروني يحتوي على نصوص برمجية يجب أن تشير إلى عناصر النموذج. الغرض من النموذج هو جمع المعلومات التي يقدمها المستخدم عبر لوحة المفاتيح/الماوس وإرسالها إلى عنوان خادم ويب. أي عنوان؟ العنوان المشار إليه في السمة action="URL". إذا كان هذا السمة غائبًا، فسيتم إرسال المعلومات إلى خادم المستند الذي يوجد فيه النموذج. وهذا هو الحال في المثال أعلاه. حتى الآن، كنا ننظر دائمًا إلى عميل الويب على أنه "يطلب" معلومات من خادم الويب، ولم ننظر إليه أبدًا على أنه "يقدم" معلومات له. كيف يقوم عميل الويب بإعطاء المعلومات (الموجودة في النموذج) إلى خادم الويب؟ سنعود إلى هذا بالتفصيل لاحقًا. يمكنه استخدام طريقتين مختلفتين تسميان POST و GET. السمة method="méthode"، مع طريقة تساوي GET أو POST، في العلامة <form> يحدد للمتصفح الطريقة التي يجب استخدامها لإرسال المعلومات التي تم جمعها في النموذج إلى URL المحددة بواسطة السمة action="URL". عندما لا يتم تحديد السمة method، يتم استخدام الطريقة GET بشكل افتراضي. |
2.7.1.2. حقل الإدخال
![]()
![]()
<input type="text" name="txtSaisie" size="20" value="بضع كلمات"> <input type="password" name="txtMdp" size="20" value="unMotDePasse"> |
<input type="..." name="..." size=".." value=".."> تتوفر علامة input لمختلف عناصر التحكم. والسمة type هي التي تسمح بالتمييز بين عناصر التحكم المختلفة هذه. | |
type="text": يحدد أن هذا حقل إدخال type="password": يتم استبدال الأحرف الموجودة في حقل الإدخال بأحرف *. وهذا هو الفرق الوحيد عن حقل الإدخال العادي. هذا النوع من عناصر التحكم مناسب لإدخال كلمات المرور. size="20": عدد الأحرف المرئية في الحقل - لا يمنع إدخال المزيد من الأحرف name="txtSaisie": اسم عنصر التحكم value="بعض الكلمات": النص الذي سيتم عرضه في حقل الإدخال. |
2.7.1.3. حقل إدخال متعدد الأسطر
![]()
<textarea rows="2" name="areaSaisie" cols="20"> ligne1 ligne2 ligne3 </textarea> |
<textarea ...>نص</textarea> يعرض منطقة إدخال متعددة الأسطر مع وجود نص بداخلها في البداية | |
rows="2": عدد الأسطر cols="'20" : عدد الأعمدة name="areaSaisie": اسم عنصر التحكم |
2.7.1.4. أزرار الاختيار
![]()
<input type="radio" value="نعم" name="R1">نعم <input type="radio" name="R1" value="لا" checked>لا |
<input type="radio" attribut2="valeur2" ....>نص يعرض زر اختيار مع نص بجانبه. | |
name="radio": اسم عنصر التحكم. تشكل أزرار الاختيار التي تحمل الاسم نفسه مجموعة من الأزرار المتنافية: لا يمكن تحديد سوى واحد منها. value="القيمة" : القيمة المخصصة لزر الاختيار. لا يجب الخلط بين هذه القيمة والنص المعروض بجانب زر الاختيار. فهذا النص مخصص للعرض فقط. checked: إذا كانت هذه الكلمة الرئيسية موجودة، يكون زر الاختيار محددًا، وإلا فإنه غير محدد. |
2.7.1.5. مربعات الاختيار
<input type="checkbox" name="C1" value="واحد">1 <input type="checkbox" name="C2" value="deux" checked>2 <input type="checkbox" name="C3" value="ثلاثة">3 |
![]()
<input type="checkbox" attribut2="valeur2" ....>نص يعرض مربع اختيار مع نص بجانبه. | |
name="C1": اسم عنصر التحكم. يمكن أن تحمل مربعات الاختيار نفس الاسم أو لا. تشكل المربعات التي تحمل نفس الاسم مجموعة من المربعات المرتبطة. value="القيمة": القيمة المخصصة لمربع الاختيار. لا يجب الخلط بين هذه القيمة والنص المعروض بجانب زر الاختيار. فهذا النص مخصص للعرض فقط. checked: إذا كانت هذه الكلمة الرئيسية موجودة، يكون زر الاختيار محددًا، وإلا فإنه غير محدد. |
2.7.1.6. قائمة منسدلة (combo)
<select size="1" name="cmbValeurs"> <option>choix1</option> <option selected>الخيار 2</option> <option>choix3</option> </select> |
![]()
<select size=".." name=".."> <option [selected]>...</option> ... </select> يعرض في قائمة النصوص الموجودة بين العلامات <option>...</option> | |
name="cmbValeurs": اسم عنصر التحكم. size="1": عدد عناصر القائمة المرئية. size="1" يجعل القائمة تعادل مربع الاختيار. selected: إذا كانت هذه الكلمة الرئيسية موجودة لعنصر في القائمة، فسيظهر هذا العنصر محددًا في القائمة. في المثال أعلاه، يظهر عنصر القائمة choix2 كعنصر محدد في مربع الاختيار عند عرضه لأول مرة. |
2.7.1.7. قائمة ذات اختيار واحد
<select size="3" name="lst1"> <option selected>liste1</option> <option>liste2</option> <option>liste3</option> <option>liste4</option> <option>liste5</option> </select> |

<select size=".." name=".."> <option [selected]>...</option> ... </select> يعرض في قائمة النصوص الموجودة بين العلامات <option>...</option> | |
نفس العناصر الموجودة في القائمة المنسدلة التي تعرض عنصرًا واحدًا فقط. لا يختلف هذا العنصر عن القائمة المنسدلة السابقة إلا في سمة size>1. |
2.7.1.8. قائمة متعددة الاختيارات
<select size="3" name="lst2" multiple> <option selected>liste1</option> <option>liste2</option> <option selected>القائمة 3</option> <option>liste4</option> <option>liste5</option> </select> |

<select size=".." name=".." multiple> <option [selected]>...</option> ... </select> يعرض في قائمة النصوص الموجودة بين العلامات <option>...</option> | |
multiple: يسمح بتحديد عدة عناصر في القائمة. في المثال أعلاه، تم تحديد العنصرين liste1 و liste3. |
2.7.1.9. زر من النوع button
<input type="button" value="مسح" name="cmdEffacer" onclick="effacer()"> |
![]()
<input type="button" value="..." name="..." onclick="effacer()" ....> | |
type="button": يحدد عنصر تحكم زر. هناك نوعان آخران من الأزرار، وهما submit و reset. value="حذف": النص المعروض على الزر onclick="وظيفة()": يسمح بتعريف وظيفة يتم تنفيذها عندما ينقر المستخدم على الزر. هذه الوظيفة هي جزء من البرامج النصية المحددة في المستند الويب المعروض. الصيغة السابقة هي صيغة javascript. إذا كانت البرامج النصية مكتوبة بلغة vbscript، فيجب كتابة onclick="وظيفة" بدون الأقواس. تصبح الصيغة متطابقة إذا كان من الضروري تمرير معلمات إلى الدالة: onclick="dالة(val1, val2,...)" في مثالنا، يؤدي النقر على الزر Effacer إلى استدعاء وظيفة جافا سكريبت effacer التالية: تعرض الوظيفة effacer رسالةً تقول: ![]() |
2.7.1.10. زر من نوع submit
<input type="submit" value="إرسال" name="cmdRenvoyer"> |
![]()
<input type="submit" value="إرسال" name="cmdRenvoyer"> | |
type="submit": يحدد الزر كزر لإرسال بيانات النموذج إلى خادم الويب. عندما ينقر العميل على هذا الزر، سيرسل المتصفح بيانات النموذج إلى URL المحددة في سمة action لعلامة <form> وفقًا للطريقة المحددة بواسطة سمة method لنفس العلامة. value="إرسال": النص المعروض على الزر |
2.7.1.11. زر من نوع reset
<input type="reset" value="إعادة الضبط" name="cmdRétablir"> |
![]()
<input type="reset" value="إعادة الضبط" name="cmdRétablir"> | |
type="reset": يحدد الزر كزر لإعادة تعيين النموذج. عندما ينقر العميل على هذا الزر، سيعيد المتصفح النموذج إلى الحالة التي استلمه بها. value="إعادة تعيين": النص المعروض على الزر |
2.7.1.12. حقل مخفي
<input type="hidden" name="secret" value="uneValeur"> |
<input type="hidden" name="..." value="..."> | |
type="hidden": يحدد أن هذا حقل مخفي. الحقل المخفي جزء من النموذج ولكنه لا يظهر للمستخدم. ومع ذلك، إذا طلب المستخدم من متصفحه عرض شفرة المصدر، فسيرى وجود العلامة <input type="hidden" value="..."> وبالتالي قيمة الحقل المخفي. value="uneValeur": قيمة الحقل المخفي. ما فائدة الحقل المخفي؟ يمكن أن يسمح ذلك لخادم الويب بالاحتفاظ بالمعلومات على مدار طلبات العميل. لنفترض وجود تطبيق للتسوق عبر الويب. يشتري العميل منتجًا أول art1 بكمية q1 على الصفحة الأولى من الكتالوج ثم ينتقل إلى صفحة جديدة من الكتالوج. ولتذكر أن العميل اشترى q1 و art1، يمكن للخادم وضع هاتين المعلومتين في حقل مخفي في نموذج الويب الخاص بالصفحة الجديدة. في هذه الصفحة الجديدة، يشتري العميل المنتجين q2 و art2. عندما يتم إرسال بيانات هذا النموذج الثاني إلى الخادم (submit)، لن يتلقى الخادم المعلومات (q2،art2) فحسب، بل أيضًا (q1،art1) التي تشكل أيضًا جزءًا من النموذج كحقل مخفي لا يمكن للمستخدم تعديله. ثم سيضع خادم الويب المعلومات (q1,art1) و (q2,art2) في حقل مخفي جديد ويرسل صفحة جديدة من الكتالوج. وهكذا دواليك. |
2.7.2. إرسال قيم نموذج من عميل ويب إلى خادم ويب
ذكرنا في الدراسة السابقة أن عميل الويب لديه طريقتان لإرسال قيم نموذج قام بعرضه إلى خادم ويب: الطريقتان GET و POST. لنرى من خلال مثال الفرق بين الطريقتين. الصفحة التي درسناها سابقًا هي صفحة ثابتة. من أجل الوصول إلى الرؤوس HTTP المرسلة من المتصفح الذي سيطلب هذا المستند، نقوم بتحويلها إلى صفحة ديناميكية لخادم ويب .NET (IIS أو Cassini). لا يتعلق الأمر هنا بالتكنولوجيا .NET التي سيتم تناولها في الفصل التالي، بل بالتبادلات بين العميل والخادم. رمز الصفحة ASP.NET هو التالي:
<%@ Page Language="vb" CodeBehind="params.aspx.vb" AutoEventWireup="false" Inherits="ConsoleApplication1.params" %>
<script runat="server">
Private Sub Page_Init(Byval Sender as Object, Byval e as System.EventArgs)
' يتم حفظ الطلب
saveRequest
end sub
Private Sub saveRequest
' حفظ الطلب الحالي في request.txt من مجلد الصفحة
dim requestFileName as String=Me.MapPath(Me.TemplateSourceDirectory)+"\request.txt"
Me.Request.SaveAs(requestFileName,true)
end sub
</script>
<html>
<head>
<title>balises</title>
<script language="JavaScript">
function effacer(){
alert("Vous avez cliqué sur le bouton Effacer");
}//مسح
</script>
</head>
<body background="/images/standard.jpg">
....
</body>
</html>
إلى محتوى HTML للصفحة قيد الدراسة، نضيف جزءًا من الكود في VB.NET. لن نعلق على هذا الكود، سوى أن نقول إنه عند كل استدعاء للوثيقة المذكورة أعلاه، سيقوم خادم الويب بحفظ طلب العميل في ملف [request.txt] في مجلد الوثيقة المستدعاة.
2.7.2.1. طريقة GET
لنقم بإجراء اختبار أولي، حيث في الكود HTML للوثيقة، يتم تعريف العلامة FORM على النحو التالي:
<form method="get">
يُسمى المستند السابق (HTML+رمز VB) [params.aspx]. يتم وضعه في شجرة خادم الويب .NET (IIS/Cassini) ويتم استدعاؤه باستخدام عنوان URL http://localhost/aspnet/chap1/params.aspx:

قام المتصفح للتو بإرسال طلب ونعلم أن هذا الطلب قد تم تسجيله في الملف [request.txt]. لنلقِ نظرة على محتوى هذا الملف:
GET /aspnet/chap1/params.aspx HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113
نجد عناصر سبق أن صادفناها مع العميل [curl]. وتظهر عناصر أخرى للمرة الأولى:
يطلب العميل من الخادم عدم إغلاق الاتصال بعد الرد. سيسمح له ذلك باستخدام نفس الاتصال لطلب لاحق. لا يبقى الاتصال مفتوحًا إلى أجل غير مسمى. سيقوم الخادم بإغلاقه بعد فترة طويلة من عدم الاستخدام. | |
المدة بالثواني التي سيبقى خلالها الاتصال [Keep-Alive] مفتوحًا | |
فئة الأحرف التي يستطيع العميل التعامل معها | |
قائمة اللغات المفضلة لدى العميل. |
نملأ النموذج بالطريقة التالية:

نستخدم الزر [Envoyer] أعلاه. رمزه HTML هو التالي:
عند تنشيط زر من النوع [Submit]، يرسل المتصفح معلمات النموذج (العلامة <form>) إلى URL المحددة في السمة [action] للعلامة <form action="URL"> إن وجدت. إذا لم يكن هذا السمة موجودًا، يتم إرسال معلمات النموذج إلى URL الذي أنشأ النموذج. وهذا هو الحال هنا. لذلك، من المفترض أن يؤدي الزر [Envoyer] إلى إرسال طلب من المتصفح إلى URL [http://localhost/aspnet/chap1/params.aspx] مع نقل معلمات النموذج. نظرًا لأن الصفحة [params.aspx] تحتفظ بالطلب المستلم، يجب أن نعرف كيف قام العميل بنقل هذه المعلمات. لنجرب ذلك. نضغط على الزر [Envoyer]. نتلقى الرد التالي من المتصفح:

هذه هي الصفحة الأولية، ولكن يمكننا ملاحظة أن URL قد تغير في حقل [Adresse] بالمتصفح. وأصبح كما يلي:
http://localhost/aspnet/chap1/params.aspx?R1=نعم&C1=واحد&C2=اثنان&txtSaisie=برمجة+الويب&txtMdp=هذا_سر&areaSaisie=أساسيات_البرمجة_الويب&0D%0أساسيات+برمجة+الويب&cmbValeurs=الخيار3&lst1=القائمة3&lst2=القائمة1&lst2=القائمة3&cmdRenvoyer=إرسال&secret=uneValeur
نلاحظ أن الاختيارات التي تمت في النموذج موجودة في URL. لنلقِ نظرة على محتوى الملف [request.txt] الذي سجل طلب العميل:
GET /aspnet/chap1/params.aspx?R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecret&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&cmdRenvoyer=Envoyer&secret=uneValeur HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
Referer: http://localhost/aspnet/chap1/params.aspx
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113
نجد طلبًا HTTP مشابهًا إلى حد كبير للطلب الذي قدمه المتصفح في البداية عندما طلب المستند دون إرسال أي معلمات. هناك اختلافان:
تمت إضافة معلمات النموذج بعد URL الخاص بالوثيقة على النحو التالي: ?param1=val1¶m2=val2&... | |
يُشير العميل من خلال هذا العنوان HTTP إلى URL الخاص بالوثيقة التي كان يعرضها عند إجراء الطلب |
دعونا نلقي نظرة فاحصة على كيفية تمرير المعلمات في الأمر GET URL?param1=value1¶m2=value2&... HTTP/1.1 حيث parami هي أسماء عناصر التحكم في نموذج الويب و valeuri هي القيم المرتبطة بها. نقدم أدناه جدولًا مكونًا من ثلاثة أعمدة:
- العمود 1: يتضمن تعريف عنصر تحكم HTML من المثال
- العمود 2: يعرض شكل هذا عنصر التحكم في المتصفح
- العمود 3: يعرض القيمة التي يرسلها المتصفح إلى الخادم لعنصر التحكم في العمود 1 بالشكل الذي تظهر به في الاستعلام GET في المثال
عنصر التحكم HTML | المرئي | القيمة (القيم) المرتجعة |
<input type="radio" value="نعم" name="R1">نعم <input type="radio" name="R1" value="لا" checked>لا | R1=نعم - قيمة السمة value للزر الإذاعي الذي حدده المستخدم. | |
<input type="checkbox" name="C1" value="واحد">1 <input type="checkbox" name="C2" value="اثنان" checked>2 <input type="checkbox" name="C3" value="ثلاثة">3 | C1=واحد C2=اثنان - قيم سمات value للمربعات التي حددها المستخدم | |
<input type="text" name="txtSaisie" size="20" value="بضع كلمات"> | txtSaisie=برمجة+الويب - النص الذي كتبه المستخدم في حقل الإدخال. تم استبدال المسافات بعلامة + | |
<input type="password" name="txtMdp" size="20" value="unMotDePasse"> | txtMdp=هذا_سر - النص الذي يكتبه المستخدم في حقل الإدخال | |
<textarea rows="2" name="areaSaisie" cols="20"> السطر 1 السطر 2 السطر 3 </textarea> | areaSaisie=أساسيات+البرمجة+الويب%0D%0A البرمجة+الويب - النص الذي أدخله المستخدم في حقل الإدخال. %OD%OA هي علامة نهاية السطر. تم استبدال المسافات بعلامة + | |
<select size="1" name="cmbValeurs"> <option>الخيار1</option> <option selected>الخيار 2</option> <option>الخيار 3</option> </select> | cmbValeurs=الخيار3 - القيمة التي اختارها المستخدم من قائمة الاختيار الفردي | |
<select size="3" name="lst1"> <option selected>liste1</option> <option>القائمة 2</option> <option>القائمة 3</option> <option>القائمة 4</option> <option>القائمة 5</option> </select> | ![]() | lst1=liste3 - القيمة التي اختارها المستخدم من قائمة الاختيار الفردي |
<select size="3" name="lst2" multiple> <option selected>liste1</option> <option>القائمة 2</option> <option selected>القائمة 3</option> <option>القائمة 4</option> <option>القائمة 5</option> </select> | ![]() | lst2=القائمة 1 lst2=القائمة 3 - القيم التي اختارها المستخدم من قائمة الاختيار المتعدد |
<input type="submit" value="إرسال" name="cmdRenvoyer"> | cmdRenvoyer=إرسال - اسم وسمة value للزر الذي استُخدم لإرسال بيانات النموذج إلى الخادم | |
<input type="hidden" name="secret" value="uneValeur"> | secret=قيمة - السمة value للحقل المخفي |
قد يتساءل المرء عما فعله الخادم بالمعلمات التي تم تمريرها إليه. في الواقع، لم يفعل شيئًا. عند استلام الأمر
GET /aspnet/chap1/params.aspx?R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecret&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&cmdRenvoyer=Envoyer&secret=uneValeur HTTP/1.1
قام خادم الويب بنقل المعلمات إلى URL إلى المستند http://localhost/aspnet/chap1/params.aspx، و c.a.d إلى المستند الذي أنشأناه في البداية. لم نكتب أي كود لاسترداد ومعالجة المعلمات التي يرسلها لنا العميل. لذا، يبدو الأمر كما لو أن طلب العميل كان ببساطة:
ولهذا السبب، استجابةً لزرنا [Envoyer]، حصلنا على نفس الصفحة التي حصلنا عليها في البداية عند طلب URL [http://localhost/aspnet/chap1/params.aspx] بدون معلمات.
2.7.2.2. طريقة POST
تمت برمجة المستند HTML بحيث يستخدم المتصفح الآن طريقة POST لإرسال قيم النموذج إلى خادم الويب:
نطلب المستند الجديد عبر URL [http://localhost/aspnet/chap1/params.aspx]، ونملأ النموذج كما في الطريقة GET ونرسل المعلمات إلى الخادم باستخدام الزر [Envoyer]. نحصل من الخادم على صفحة الرد التالية:

وبالتالي نحصل على نفس النتيجة التي حصلنا عليها باستخدام الطريقة GET، c.a.d. الصفحة الأولية. سنلاحظ اختلافًا: في حقل [Adresse] بالمتصفح، لا تظهر المعلمات المرسلة. الآن، لنلقِ نظرة على الطلب الذي أرسله العميل والذي تم تخزينه في الملف [request.txt]:
POST /aspnet/chap1/params.aspx HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Content-Length: 210
Content-Type: application/x-www-form-urlencoded
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
Referer: http://localhost/aspnet/chap1/params.aspx
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113
R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecrey&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&cmdRenvoyer=Envoyer&secret=uneValeur
تظهر مستجدات في استعلام العميل HTTP:
استبدل الاستعلام GET باستعلام POST. لم تعد المعلمات موجودة في السطر الأول من الاستعلام. يمكن ملاحظة أنها أصبحت الآن موضوعة بعد الاستعلام HTTP بعد سطر فارغ. ترميزها مطابق للترميز الذي كانت عليه في الاستعلام GET. | |
عدد الأحرف "المرسلة"، c.a.d. عدد الأحرف التي سيتعين على خادم الويب قراءتها بعد استلام الرؤوس HTTP لاسترداد المستند الذي يرسله إليه العميل. المستند المعني هنا هو قائمة قيم النموذج. | |
يحدد نوع المستند الذي سيرسله العميل بعد الرؤوس HTTP. يشير النوع [application/x-www-form-urlencoded] إلى أنه مستند يحتوي على قيم النموذج. |
هناك طريقتان لنقل البيانات إلى خادم الويب: GET و POST. هل هناك طريقة أفضل من الأخرى؟ لقد رأينا أنه إذا تم إرسال قيم النموذج بواسطة المتصفح باستخدام الطريقة GET، فإن المتصفح يعرض في حقل Adresse الخاص به القيمة المطلوبة URL بالصيغة URL?param1=val1¶m2=val2&.... يمكن اعتبار ذلك ميزة أو عيبًا:
- ميزة إذا كنا نريد السماح للمستخدم بوضع هذا الرابط URL المُعد في قائمة الروابط المفضلة لديه
- عيب إذا كنا لا نرغب في أن يتمكن المستخدم من الوصول إلى بعض المعلومات في النموذج، مثل الحقول المخفية على سبيل المثال
بعد ذلك، سنستخدم طريقة POST بشكل حصري تقريبًا في نماذجنا.
2.8. Conclusion
عرض هذا الفصل مفاهيم أساسية مختلفة لتطوير الويب:
- الأدوات والتقنيات المختلفة المتاحة (java، asp، asp.net، php، perl، vbscript، javascript)
- التبادل بين العميل والخادم عبر بروتوكول HTTP
- تصميم مستند باستخدام لغة HTML
- تصميم نماذج الإدخال
لقد رأينا في أحد الأمثلة كيف يمكن للعميل إرسال المعلومات إلى خادم الويب. لم نعرض كيف يمكن للخادم
- استرداد هذه المعلومات
- معالجتها
- إرسال رد ديناميكي إلى العميل بناءً على نتيجة المعالجة
هذا هو مجال برمجة الويب، وهو مجال سنتناوله في الفصل التالي مع عرض تقنية ASP.NET.


