2. الأساسيات
في هذا الفصل، نقدم أساسيات برمجة الويب. ويتمثل الهدف الأساسي منه في تعريف القارئ بالمبادئ الرئيسية لبرمجة الويب قبل تطبيقها عمليًا باستخدام لغة وبيئة معينتين. ويقدم الفصل العديد من الأمثلة التي يُنصح بتجربتها من أجل «الانغماس» تدريجيًا في فلسفة تطوير الويب.
2.1. مكونات تطبيق الويب

رقم | الدور | أمثلة شائعة |
OS الخادم | Linux، Windows | |
خادم الويب | أباتشي (لينكس، ويندوز) IIS (NT)، PWS (Win9x) | |
نصوص برمجية تُنفَّذ على جانب الخادم. ويمكن تنفيذها بواسطة وحدات الخادم أو بواسطة برامج خارجية (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) Access (ويندوز) SQL Server (ويندوز) | |
OS العميل | لينكس، ويندوز | |
متصفح الويب | نتسكيب، إنترنت إكسبلورر | |
نصوص برمجية تُنفَّذ من جانب العميل داخل المتصفح. لا تتمتع هذه البرامج النصية بأي وصول إلى أقراص جهاز العميل. | 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. بعض الموارد
فيما يلي قائمة بالموارد التي تتيح تثبيت واستخدام بعض الأدوات اللازمة لتطوير الويب. وتوجد في الملحق إرشادات حول كيفية تثبيت هذه الأدوات.
http://www.apache.org - Apache، التثبيت والتشغيل، O'Reilly | |
http://www.microsoft.com | |
http://www.activestate.com - البرمجة بلغة بيرل، لاري وول، أورايلي - تطبيقات CGI بلغة بيرل، نيوس وفرومانز، أورايلي - الوثائق المرفقة مع Active Perl | |
http://www.php.net - البرمجة على الويب باستخدام PHP، لاكروا، إيرول - دليل استخدام PHP المتاح على موقع PHP | |
http://msdn.microsoft.com/scripting/vbscript/download/vbsdoc.exe http://msdn.microsoft.com/scripting/default.htm?/scripting/vbscript - واجهة بين WEB وقاعدة البيانات تحت WinNT، أليكس هومر، Eyrolles | |
http://msdn.microsoft.com/scripting/jscript/download/jsdoc.exe http://developer.netscape.com/docs/manuals/index.html | |
http://developer.netscape.com/docs/manuals/index.html | |
http://www.sun.com - JAVA Servlets، جيسون هانتر، أورايلي - البرمجة الشبكية باستخدام Java، إليوت روستي هارولد، أورايلي - JDBC و Java، جورج ريس، أورايلي | |
http://www.mysql.com http://www.oracle.com - دليل MySQL متاح على موقع MySQL - Oracle 8i على نظام Linux، جيل بريارد، دار إيرول - Oracle 8i على نظام NT، جيل بريارد، دار إيرول |
2.4. التعريفات
فيما يلي، سنفترض أن عددًا معينًا من الأدوات قد تم تثبيته وسنستخدم الرموز التالية:
الرمز | المعنى |
جذر شجرة الخادم 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. | |
جذر صفحات الويب التي يقدمها PWS. يجب أن توجد صفحات الويب ضمن هذا المجلد الجذري. وبالتالي، فإن URL http://localhost/page1.htm يتوافق مع الملف <pws-DocumentRoot>\page1.htm. | |
جذر شجرة لغة بيرل. عادةً ما يوجد الملف القابل للتنفيذ perl.exe في <perl>\bin. | |
جذر شجرة لغة PHP. عادةً ما يوجد الملف القابل للتنفيذ php.exe في <php>. | |
جذر شجرة جافا. توجد الملفات التنفيذية المرتبطة بجافا في <java>\bin. | |
جذر خادم Tomcat. توجد أمثلة على السيرفلتات في <tomcat>\webapps\examples\servlets وأمثلة على الصفحات في JSP في <tomcat>\webbapps\examples\jsp |
يرجى الرجوع إلى الملحق الخاص بكل أداة من هذه الأدوات للحصول على إرشادات حول تثبيتها.
2.5. صفحات الويب الثابتة، صفحات الويب الديناميكية
يتم تمثيل الصفحة الثابتة بملف HTML. أما الصفحة الديناميكية، فيتم إنشاؤها «على الفور» بواسطة خادم الويب. نقدم لكم في هذه الفقرة اختبارات متنوعة باستخدام خوادم ويب مختلفة ولغات برمجة مختلفة لإظهار عالمية مفهوم الويب.
2.5.1. الصفحة الثابتة HTML (لغة الترميز HyperText)
لننظر إلى الكود HTML التالي:
<html>
<head>
<title>essai 1 : une page statique</title>
</head>
<body>
<center>
<h1>Une page statique...</h1>
</body>
</html>
الذي ينتج الصفحة التالية:
الاختبارات

-
تشغيل خادم Apache
-
وضع البرنامج النصي essai1.html في <apache-DocumentRoot>
-
عرض ملف URL http://localhost/essai1.html باستخدام متصفح
-
إيقاف تشغيل خادم Apache
-
تشغيل خادم PWS
-
وضع البرنامج النصي essai1.html في <pws-DocumentRoot>
-
عرض صفحة URL http://localhost/essai1.html باستخدام متصفح
2.5.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>
ينتج الصفحة التالية:

الاختبار
-
تشغيل الخادم PWS
-
وضع البرنامج النصي essai2.asp في <pws-DocumentRoot>
-
طلب صفحة URL http://localhost/essai2.asp باستخدام متصفح
2.5.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>
-
اطلب الرابط http://localhost/cgi-bin/essai3.pl
تجدر الإشارة إلى أن عرض الصفحة perl يستغرق وقتًا أطول من عرض الصفحة asp. ويرجع ذلك إلى أن البرنامج النصي Perl يتم تنفيذه بواسطة مترجم لغة Perl الذي يجب تحميله قبل أن يتمكن من تنفيذ البرنامج النصي. ولا يبقى هذا المترجم في الذاكرة بشكل دائم.
2.5.4. نص برمجي PHP (الصفحة الرئيسية الشخصية)
البرنامج النصي 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>
ينتج البرنامج النصي السابق الصفحة التالية:
الاختبارات


-
راجع ملف التكوين srm.conf أو httpd.conf الخاص بـ Apache في <Apache>\confs
-
للعلم، تحقق من أسطر التكوين في ملف php
-
قم بتشغيل خادم Apache
-
ضع ملف essai4.php في <apache-DocumentRoot>
-
اطلب URL http://localhost/essai4.php
-
تشغيل خادم PWS
-
للعلم، التحقق من إعدادات PWS فيما يتعلق بـ php
-
وضع essai4.php في <pws-DocumentRoot>\php
-
طلب URL http://localhost/essai4.php
2.5.5. نص برمجي JSP (Java Server Pages)
البرنامج النصي 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.5.6. الخلاصة
أظهرت الأمثلة السابقة ما يلي:
- يمكن إنشاء صفحة HTML ديناميكيًا بواسطة برنامج. وهذا هو جوهر البرمجة على الويب.
- أن لغات البرمجة وخوادم الويب المستخدمة يمكن أن تكون متنوعة. ونلاحظ حاليًا الاتجاهات الرئيسية التالية:
- الثنائيات Apache/PHP (ويندوز، لينكس) و IIS/PHP (ويندوز)
- تقنية ASP.NET على منصات Windows التي تجمع بين خادم IIS ولغة .NET (C#، VB.NET، ...)
- تقنية سيرفلتات Java وصفحات JSP التي تعمل مع خوادم مختلفة (Tomcat، Apache، IIS) وعلى منصات مختلفة (Windows، Linux). وستتم مناقشة هذه التقنية الأخيرة بشكل أكثر تفصيلاً في هذا المستند.
2.6. البرامج النصية من جانب المتصفح
يمكن أن تحتوي صفحة HTML على نصوص برمجية يتم تنفيذها بواسطة المتصفح. هناك العديد من لغات البرمجة من جانب المتصفح. وفيما يلي بعض منها:
اللغة | المتصفحات التي تدعمها |
Vbscript | IE |
جافا سكريبت | IE، Netscape |
PerlScript | IE |
جافا | IE، Netscape |
لنأخذ بعض الأمثلة.
2.6.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
-
خادم PWS
-
البرنامج النصي vbs1.html في <pws-DocumentRoot>
-
طلب الرابط http://localhost/vbs1.html باستخدام متصفح IE
2.6.2. صفحة ويب تحتوي على برنامج نصي جافا سكريبت، من جانب المتصفح
الصفحة: 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 ونتسكيب. ويؤدي تنفيذها إلى نفس النتائج:

الاختبارات
-
خادم Apache
-
البرنامج النصي js1.html في <apache-DocumentRoot>
-
طلب الرابط http://localhost/js1.html باستخدام متصفح IE أو Netscape
-
خادم PWS
-
البرنامج النصي js1.html في <pws-DocumentRoot>
-
اطلب عنوان URL http://localhost/js1.html باستخدام متصفح IE أو Netscape
2.7. التفاعلات بين العميل والخادم
لنعد إلى الرسم التخطيطي الأولي الذي يوضح العناصر الفاعلة في تطبيق ويب:
![]() |
نركز هنا على التبادلات بين جهاز العميل وجهاز الخادم. تتم هذه التبادلات عبر شبكة، ومن الجيد التذكير بالبنية العامة للتبادلات بين جهازين بعيدين.
2.7.1. النموذج OSI
يصف نموذج الشبكة المفتوحة المسمى OSI (نموذج مرجعي لترابط الأنظمة المفتوحة)، الذي حددته المنظمة الدولية للمعايير (ISO)، شبكةً مثاليةً يمكن فيها تمثيل الاتصال بين الأجهزة بنموذج مكون من سبع طبقات:
![]() |
تتلقى كل طبقة الخدمات من الطبقة السفلية وتقدم خدماتها إلى الطبقة العليا. لنفترض أن تطبيقين موجودين على جهازين مختلفين، A و B، يرغبان في التواصل: فيقومان بذلك على مستوى الطبقة Application. ولا يحتاجان إلى معرفة كل تفاصيل عمل الشبكة: فكل تطبيق يسلم المعلومات التي يرغب في إرسالها إلى الطبقة التي تليه مباشرةً، وهي الطبقة Présentation. وبالتالي، لا يتعين على التطبيق سوى معرفة قواعد التفاعل مع الطبقة Présentation. وبمجرد وصول المعلومات إلى الطبقة Présentation، يتم تمريرها وفقًا لقواعد أخرى إلى الطبقة Session وهكذا دواليك، حتى تصل المعلومات إلى الوسيط المادي ويتم إرسالها فعليًّا إلى الجهاز المقصود. وهناك، ستخضع لعملية معالجة عكسية لتلك التي خضعت لها على الجهاز المرسل.
في كل طبقة، تقوم العملية المرسلة المكلفة بإرسال المعلومات بإرسالها إلى عملية مستقبلة على الجهاز الآخر الذي ينتمي إلى نفس الطبقة التي تنتمي إليها. وتقوم بذلك وفقًا لقواعد معينة تُسمى بروتوكول الطبقة. وبذلك نحصل على مخطط الاتصال النهائي التالي:
![]() |
دور الطبقات المختلفة هو كما يلي:
تضمن نقل البتات عبر وسيط مادي. توجد في هذه الطبقة أجهزة طرفية لمعالجة البيانات (E.T.T.D.) مثل المحطة الطرفية أو الكمبيوتر، بالإضافة إلى أجهزة إنهاء دوائر البيانات (E.T.C.D.) مثل المُعدِّل/المُفكِّك، والمُضاعِف، والمُركِّز. النقاط المهمة في هذا المستوى هي: . اختيار طريقة ترميز المعلومات (تناظرية أو رقمية) . اختيار طريقة الإرسال (متزامنة أو غير متزامنة). | |
يخفي الخصائص الفيزيائية للطبقة المادية. يكتشف أخطاء الإرسال ويصححها. | |
يدير المسار الذي يجب أن تتبعه المعلومات المرسلة عبر الشبكة. ويُطلق على ذلك اسم routage: تحديد المسار الذي يجب أن تتبعه المعلومات حتى تصل إلى مستلمها. | |
تسمح بالاتصال بين تطبيقين، في حين أن الطبقات السابقة كانت تسمح فقط بالاتصال بين الأجهزة. ومن الخدمات التي توفرها هذه الطبقة «التعدد الإرسالي»: حيث يمكن لطبقة النقل استخدام نفس اتصال الشبكة (من جهاز إلى جهاز) لنقل المعلومات الخاصة بعدة تطبيقات. | |
نجد في هذه الطبقة خدمات تسمح لأحد التطبيقات بفتح جلسة عمل والحفاظ عليها على جهاز بعيد. | |
وتهدف هذه الطبقة إلى توحيد عرض البيانات على الأجهزة المختلفة. وبالتالي، فإن البيانات الواردة من الجهاز «أ» سيتم «تنسيقها» بواسطة طبقة Présentation الخاصة بالجهاز «أ»، وفقًا لتنسيق قياسي قبل إرسالها عبر الشبكة. وعند وصولها إلى الطبقة Présentation في الجهاز المستلم B، الذي سيتعرف عليها بفضل تنسيقها القياسي، سيتم تكييفها بطريقة أخرى حتى يتعرف عليها تطبيق الجهاز B. | |
في هذه المرحلة، نجد التطبيقات التي عادةً ما تكون قريبة من المستخدم، مثل البريد الإلكتروني أو نقل الملفات. |
2.7.2. النموذج TCP/IP
يُعد النموذج OSI نموذجًا مثاليًّا. وتقترب مجموعة البروتوكولات TCP/IP منه بالشكل التالي:
![]() |
- تؤدي واجهة الشبكة (بطاقة الشبكة في الكمبيوتر) وظائف الطبقتين 1 و2 من النموذج OSI
- تؤدي الطبقة IP (بروتوكول الإنترنت) وظائف الطبقة الثالثة (الشبكة)
- الطبقة TCP (بروتوكول التحكم في النقل) أو UDP (بروتوكول مخطط بيانات المستخدم) تؤدي وظائف الطبقة الرابعة (النقل). يضمن بروتوكول TCP وصول حزم البيانات المتبادلة بين الأجهزة إلى وجهتها بشكل صحيح. وإذا لم يحدث ذلك، فإنه يعيد الحزم التي ضلت طريقها. لا يقوم بروتوكول UDP بهذه المهمة، وبالتالي يقع على عاتق مطور التطبيقات القيام بها. ولهذا السبب، على الإنترنت التي لا تُعد شبكة موثوقة بنسبة 100٪، يُعد بروتوكول TCP هو الأكثر استخدامًا. ونُشير عندئذٍ إلى شبكة TCP-IP.
- تغطي طبقة التطبيق وظائف المستويات من 5 إلى 7 في نموذج OSI.
توجد تطبيقات الويب في الطبقة Application، وبالتالي فهي تعتمد على بروتوكولات TCP-IP. تتبادل طبقات Application في أجهزة العملاء والخادم الرسائل التي تُعهد بها إلى الطبقات من 1 إلى 4 في النموذج لتوجيهها إلى وجهتها. وللتواصل فيما بينها، يجب أن «تتحدث» طبقات التطبيق في كلا الجهازين نفس اللغة أو البروتوكول. ويُسمى بروتوكول تطبيقات الويب HTTP (بروتوكول النقل HyperText). وهو بروتوكول نصي، c.a.d، حيث تتبادل الأجهزة أسطر نصية عبر الشبكة للتواصل فيما بينها. هذه التبادلات موحدة، بحيث يتوفر للعميل عدد معين من الرسائل للإشارة بدقة إلى ما يريده من الخادم، كما يتوفر للخادم أيضًا عدد معين من الرسائل لتقديم ردّه إلى العميل. ويأخذ تبادل الرسائل هذا الشكل التالي:
![]() |
العميل --> الخادم
عندما يوجه العميل طلبه إلى خادم الويب، فإنه يرسل
- أسطر نصية بتنسيق HTTP للإشارة إلى ما يريده
- سطر فارغ
- وثيقة (اختياري)
الخادم --> العميل
عندما يرد الخادم على العميل، فإنه يرسل
- سطور نصية بتنسيق HTTP للإشارة إلى ما يرسله
- سطر فارغ
- اختياريًا مستند
وبالتالي، تتخذ عمليات التبادل نفس الشكل في كلا الاتجاهين. وفي كلتا الحالتين، قد يتم إرسال مستند، حتى وإن كان من النادر أن يرسل العميل مستندًا إلى الخادم. لكن بروتوكول HTTP ينص على ذلك. وهذا ما يسمح، على سبيل المثال، لمشتركي مزود خدمة الإنترنت بتنزيل مستندات متنوعة على مواقعهم الشخصية المستضافة لدى هذا المزود. ويمكن أن تكون المستندات المتبادلة من أي نوع. لنأخذ مثالاً لمتصفح يطلب صفحة ويب تحتوي على صور:
- يتصل المتصفح بخادم الويب ويطلب الصفحة التي يرغب فيها. يتم تحديد الموارد المطلوبة بشكل فريد بواسطة URL (محدد موقع الموارد الموحد). لا يرسل المتصفح سوى رؤوس HTTP ولا يرسل أي مستند.
- يرد عليه الخادم. فيقوم أولاً بإرسال رؤوس HTTP تشير إلى نوع الرد الذي يرسله. وقد يكون هذا خطأً إذا كانت الصفحة المطلوبة غير موجودة. وإذا كانت الصفحة موجودة، فسيشير الخادم في رؤوس الاستجابة HTTP إلى أنه سيقوم بعد ذلك بإرسال مستند HTML (لغة الترميز HyperText). هذا المستند عبارة عن سلسلة من أسطر النص بتنسيق HTML. يحتوي النص HTML على علامات (علامات ترميز) تزود المتصفح بتوجيهات حول كيفية عرض النص.
- يعرف العميل من خلال رؤوس HTTP الصادرة عن الخادم أنه سيتلقى مستندًا بتنسيق HTML. سيقوم بتحليل هذا المستند وربما يلاحظ أنه يحتوي على إحالات إلى صور. هذه الصور غير موجودة في المستند HTML. لذا، يقوم بإرسال طلب جديد إلى نفس خادم الويب لطلب الصورة الأولى التي يحتاجها. هذا الطلب مطابق للطلب الذي تم إرساله في الخطوة 1، باستثناء أن المورد المطلوب مختلف. سيقوم الخادم بمعالجة هذا الطلب عن طريق إرسال الصورة المطلوبة إلى العميل. هذه المرة، ستوضح رؤوس HTTP في الرد أن المستند المرسل هو صورة وليس مستند HTML.
- يستلم العميل الصورة المرسلة. ستتكرر الخطوتان 3 و4 حتى يحصل العميل (وهو متصفح في العادة) على جميع المستندات التي تسمح له بعرض الصفحة بالكامل.
2.7.3. بروتوكول HTTP
لنكتشف بروتوكول HTTP من خلال أمثلة. ما الذي يتبادله المتصفح وخادم الويب؟
2.7.3.1. استجابة خادم HTTP
سنكتشف هنا كيف يستجيب خادم الويب لطلبات عملائه. خدمة الويب أو خدمة HTTP هي خدمة TCP-IP تعمل عادةً على المنفذ 80. وقد تعمل على منفذ آخر. في هذه الحالة، سيضطر متصفح العميل إلى تحديد هذا المنفذ في عنوان URL الذي يطلبه. يتخذ عنوان URL الشكل العام التالي:
البروتوكول://جهاز[:port]/المسار/المعلومات
حيث
البروتوكول | 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، يمكن للعميل أن يطلب من الخادم إبقاء الاتصال مفتوحًا حتى يطلب منه إغلاقه. وبالتالي، يمكنه استرداد جميع المستندات الخاصة بصفحة ويب عبر اتصال واحد وإغلاق الاتصال بنفسه بمجرد الحصول على آخر مستند. سيكتشف الخادم هذا الإغلاق ويقوم هو أيضًا بإغلاق الاتصال.
لاكتشاف التبادلات بين العميل وخادم الويب، سنستخدم عميلاً عامًّا باسم TCP. وهو برنامج يمكن أن يكون عميلاً لأي خدمة تستخدم بروتوكول اتصال قائم على سطور نصية، كما هو الحال مع بروتوكول HTTP. سيتم كتابة هذه الأسطر النصية بواسطة المستخدم عبر لوحة المفاتيح. وهذا يتطلب أن يكون على دراية ببروتوكول الاتصال الخاص بالخدمة التي يسعى للوصول إليها. ثم يتم عرض رد الخادم على الشاشة. تمت كتابة البرنامج بلغة Java ويمكن العثور عليه في الملحق. نستخدمه هنا في نافذة DOS ضمن نظام ويندوز ونقوم بتشغيله بالطريقة التالية:
java clientTCPgenerique machine port
مع
machine | اسم الجهاز الذي تعمل عليه الخدمة المراد الاتصال بها |
port | المنفذ الذي يتم تقديم الخدمة من خلاله |
باستخدام هاتين المعلومتين، سيقوم البرنامج بفتح اتصال TCP-IP مع الجهاز والمنفذ المحددين. سيُستخدم هذا الاتصال لتبادل أسطر النص بين العميل وخادم الويب. يكتب المستخدم سطور العميل على لوحة المفاتيح ويتم إرسالها إلى الخادم. أما سطور النص التي يرسلها الخادم كرد، فتُعرض على الشاشة. وبذلك يمكن إقامة حوار مباشر بين المستخدم الذي يستخدم لوحة المفاتيح وخادم الويب. لنجرب ذلك على الأمثلة التي سبق عرضها. كنا قد أنشأنا الصفحة الثابتة التالية: HTML:
<html>
<head>
<title>essai 1 : une page statique</title>
</head>
<body>
<center>
<h1>Une page statique...</h1>
</body>
</html>
التي نعرضها في متصفح:

نلاحظ أن الرابط URL المطلوب هو: http://localhost:81/essais/essai1.html. وبالتالي، فإن خادم خدمة الويب هو localhost (=خادم محلي) والمنفذ هو 81. وإذا طلبنا عرض نص HTML لهذه الصفحة الويب (عرض/المصدر)، فسنجد النص HTML الذي تم إنشاؤه في البداية:

الآن دعونا نستخدم عميلنا العام TCP لطلب نفس URL:
Dos>java clientTCPgenerique localhost 81
Commandes :
GET /essais/essai1.html HTTP/1.0
<-- HTTP/1.1 200 OK
<-- Date: Mon, 08 Jul 2002 08:07:46 GMT
<-- Server: Apache/1.3.24 (Win32) PHP/4.2.0
<-- Last-Modified: Mon, 08 Jul 2002 08:00:30 GMT
<-- ETag: "0-a1-3d29469e"
<-- Accept-Ranges: bytes
<-- Content-Length: 161
<-- Connection: close
<-- Content-Type: text/html
<--
<-- <html>
<-- <head>
<-- <title>essai 1 : une page statique</title>
<-- </head>
<-- <body>
<-- <center>
<-- <h1>Une page statique...</h1>
<-- </body>
<-- </html>
عند تشغيل العميل باستخدام الأمر java clientTCPgenerique localhost 81، تم إنشاء قناة اتصال بين البرنامج وخادم الويب الذي يعمل على نفس الجهاز (localhost) وعلى المنفذ 81. يمكن الآن بدء التبادل بين العميل والخادم بتنسيق HTTP. تجدر الإشارة إلى أن هذا التبادل يتكون من ثلاثة عناصر:
- رؤوس HTTP
- سطر فارغ
- بيانات اختيارية
في مثالنا، لا يرسل العميل سوى طلب واحد:
GET /essais/essai1.html HTTP/1.0
يتكون هذا السطر من ثلاثة مكونات:
الأمر HTTP لطلب مورد. وهناك أمور أخرى: HEAD تطلب موردًا ولكنها تقتصر على رؤوس HTTP في استجابة الخادم. ولا يتم إرسال المورد نفسه. PUT تسمح للعميل بإرسال مستند إلى الخادم | |
المورد المطلوب | |
مستوى بروتوكول HTTP المستخدم. هنا 1.0. وهذا يعني أن الخادم سيغلق الاتصال بمجرد إرسال استجابته |
يجب أن تتبع رؤوس الرسائل HTTP دائمًا بسطر فارغ. وهذا ما فعله العميل هنا. وبهذه الطريقة يعرف العميل أو الخادم أن الجزء HTTP من التبادل قد انتهى. هنا، يكون الأمر قد انتهى بالنسبة للعميل. فليس لديه مستند لإرساله. ثم تبدأ استجابة الخادم التي تتكون، في مثالنا، من جميع الأسطر التي تبدأ بالعلامة <--. فيرسل أولاً سلسلة من الرؤوس HTTP متبوعة بسطر فارغ:
<-- HTTP/1.1 200 OK
<-- Date: Mon, 08 Jul 2002 08:07:46 GMT
<-- Server: Apache/1.3.24 (Win32) PHP/4.2.0
<-- Last-Modified: Mon, 08 Jul 2002 08:00:30 GMT
<-- ETag: "0-a1-3d29469e"
<-- Accept-Ranges: bytes
<-- Content-Length: 161
<-- Connection: close
<-- Content-Type: text/html
<--
يقول الخادم
| |
تاريخ/وقت الرد | |
يحدد الخادم هويته. في هذه الحالة، هو خادم Apache | |
تاريخ آخر تعديل للمورد الذي طلبه العميل | |
... | |
وحدة قياس البيانات المرسلة. هنا البايت (byte) | |
عدد البايتات في المستند الذي سيتم إرساله بعد الرؤوس HTTP. هذا الرقم هو في الواقع حجم الملف بالبايت essai1.html: | |
يقول الخادم إنه سيقطع الاتصال بمجرد إرسال المستند | |
يُشير الخادم إلى أنه سيرسل نصًا (text) بتنسيق HTML (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 الذي تم إنشاؤه في البداية. إذا كان عميلنا متصفحًا، فسيقوم، بعد استلام هذه الأسطر النصية، بتفسيرها لعرض الصفحة التالية للمستخدم عبر لوحة المفاتيح:

لنستخدم مرة أخرى عميلنا العام TCP لطلب المورد نفسه، ولكن هذه المرة باستخدام الأمر HEAD الذي يطلب رؤوس الاستجابة فقط:
Dos>java.bat clientTCPgenerique localhost 81
Commandes :
HEAD /essais/essai1.html HTTP/1.1
Host: localhost:81
<-- HTTP/1.1 200 OK
<-- Date: Mon, 08 Jul 2002 09:07:25 GMT
<-- Server: Apache/1.3.24 (Win32) PHP/4.2.0
<-- Last-Modified: Mon, 08 Jul 2002 08:00:30 GMT
<-- ETag: "0-a1-3d29469e"
<-- Accept-Ranges: bytes
<-- Content-Length: 161
<-- Content-Type: text/html
<--
نحصل على نفس النتيجة التي حصلنا عليها سابقًا بدون المستند HTML. تجدر الإشارة إلى أن العميل أشار في طلبه HEAD إلى أنه يستخدم بروتوكول HTTP الإصدار 1.1. وهذا يضطره إلى إرسال رأس ثانٍ HTTP يحدد الزوج machine:port الذي يرغب العميل في الاستعلام عنه: Host: localhost:81.
الآن دعونا نطلب صورة باستخدام متصفح وكذلك باستخدام العميل العام TCP. أولاً باستخدام متصفح:

يبلغ حجم الملف univ01.gif 3167 بايت:
لنستخدم الآن العميل العام TCP:
E:\data\serge\JAVA\SOCKETS\client générique>java clientTCPgenerique localhost 81
Commandes :
HEAD /images/univ01.gif HTTP/1.1
host: localhost:81
<-- HTTP/1.1 200 OK
<-- Date: Tue, 09 Jul 2002 13:53:24 GMT
<-- Server: Apache/1.3.24 (Win32) PHP/4.2.0
<-- Last-Modified: Fri, 14 Apr 2000 11:37:42 GMT
<-- ETag: "0-c5f-38f70306"
<-- Accept-Ranges: bytes
<-- Content-Length: 3167
<-- Content-Type: image/gif
<--
يُلاحظ ما يلي في استجابة الخادم:
| |
| |
|
2.7.3.2. طلب عميل HTTP
الآن، لنطرح السؤال التالي: إذا أردنا كتابة برنامج «يتواصل» مع خادم ويب، فما هي الأوامر التي يجب أن يرسلها إلى خادم الويب للحصول على مورد معين؟ لقد حصلنا في الأمثلة السابقة على بداية إجابة. وقد صادفنا ثلاثة أوامر:
| |
| |
|
هناك أوامر أخرى. لاكتشافها، سنستخدم الآن خادمًا عامًا TCP. وهو برنامج مكتوب بلغة Java وستجده أيضًا في الملحق. يتم تشغيله بواسطة: java serveurTCPgenerique portEcoute، حيث portEcoute هو المنفذ الذي يجب على العملاء الاتصال به. البرنامج serveurTCPgenerique
- يعرض على الشاشة الأوامر المرسلة من العملاء
- ويرسل إليهم كاستجابة سطور النص التي يكتبها المستخدم على لوحة المفاتيح. وبالتالي، فإن المستخدم هو الذي يقوم بدور الخادم. في مثالنا هذا، سيؤدي المستخدم الذي يستخدم لوحة المفاتيح دور خدمة الويب.
لنحاكي الآن خادم ويب عن طريق تشغيل خادمنا العام على المنفذ 88:
Dos> java serveurTCPgenerique 88
Serveur générique lancé sur le port 88
لنستخدم الآن متصفحًا ونطلب الوصول إلى http://localhost:88/exemple.html. سيتصل المتصفح عندئذٍ بالمنفذ 88 الخاص بالجهاز localhost ثم يطلب الصفحة /exemple.html:

لنلقِ الآن نظرة على نافذة الخادم التي تعرض ما أرسله العميل إليه (تم حذف بعض الأسطر الخاصة بتشغيل البرنامج serveurTCPgenerique لتبسيط العرض):
Dos>java serveurTCPgenerique 88
Serveur générique lancé sur le port 88
...
<-- GET /exemple.html HTTP/1.1
<-- Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, */*
<-- Accept-Language: fr
<-- Accept-Encoding: gzip, deflate
<-- User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705; .NET CLR 1.0.2 914)
<-- Host: localhost:88
<-- Connection: Keep-Alive
<--
السطور التي يسبقها الرمز <-- هي تلك التي أرسلها العميل. وهكذا نكتشف رؤوس القسمات HTTP التي لم نكن قد صادفناها من قبل:
| |
| |
| |
| |
|
تنتهي الرؤوس HTTP المرسلة من المتصفح بسطر فارغ كما هو متوقع.
لنقم بإعداد رد لعميلنا. المستخدم الذي يستخدم لوحة المفاتيح هو هنا الخادم الفعلي ويمكنه إعداد الرد يدويًّا. لنتذكر الرد الذي قدمه خادم الويب في مثال سابق:
<-- HTTP/1.1 200 OK
<-- Date: Mon, 08 Jul 2002 08:07:46 GMT
<-- Server: Apache/1.3.24 (Win32) PHP/4.2.0
<-- Last-Modified: Mon, 08 Jul 2002 08:00:30 GMT
<-- ETag: "0-a1-3d29469e"
<-- Accept-Ranges: bytes
<-- Content-Length: 161
<-- Connection: close
<-- Content-Type: text/html
<--
<-- <html>
<-- <head>
<-- <title>essai 1 : une page statique</title>
<-- </head>
<-- <body>
<-- <center>
<-- <h1>Une page statique...</h1>
<-- </body>
<-- </html>
دعونا نحاول كتابة رد مماثل يدويًا (على لوحة المفاتيح). يتم إرسال الأسطر التي تبدأ بـ --> : إلى العميل:
...
<-- Host: localhost:88
<-- Connection: Keep-Alive
<--
--> : HTTP/1.1 200 OK
--> : Server: serveur tcp generique
--> : Connection: close
--> : Content-Type: text/html
--> :
--> : <html>
--> : <head><title>Serveur generique</title></head>
--> : <body>
--> : <center>
--> : <h2>Reponse du serveur generique</h2>
--> : </center>
--> : </body>
--> : </html>
fin
الأمر fin خاص بتشغيل البرنامج serveurTCPgenerique. فهو يوقف تنفيذ البرنامج ويغلق الاتصال بين الخادم والعميل. وقد اقتصرنا في ردنا على الرؤوس التالية لـ HTTP:
HTTP/1.1 200 OK
--> : Server: serveur tcp generique
--> : Connection: close
--> : Content-Type: text/html
--> :
نحن لا نحدد حجم الملف الذي سنرسله (Content-Length)، بل نكتفي بالقول إننا سنغلق الاتصال (Connection: close) بعد إرساله. وهذا يكفي للمتصفح. وعندما يرى المتصفح أن الاتصال قد أُغلق، سيعلم أن استجابة الخادم قد اكتملت، وسيقوم بعرض الصفحة HTML التي أُرسلت إليه. وهذه الصفحة هي كما يلي:
--> : <html>
--> : <head><title>Serveur generique</title></head>
--> : <body>
--> : <center>
--> : <h2>Reponse du serveur generique</h2>
--> : </center>
--> : </body>
--> : </html>
ثم يعرض المتصفح الصفحة التالية:

إذا أجرينا في ما سبق العملية View/Source لمعرفة ما تلقّاه المتصفح، فسنحصل على:

أي بالضبط ما تم إرساله من الخادم العام.
2.8. لغة HTML
يمكن لمتصفح الويب عرض مستندات متنوعة، وأكثرها شيوعًا هو مستند HTML (لغة الترميز HyperText). وهو عبارة عن نص منسق بعلامات على شكل <balise>texte</balise>. وبالتالي، فإن النص <B>important</B> سيعرض النص المهم بخط عريض. وهناك علامات منفردة مثل العلامة <hr> التي تعرض خطًا أفقيًّا. ولن نستعرض العلامات التي يمكن العثور عليها في نص HTML. توجد العديد من برامج WYSIWYG التي تتيح إنشاء صفحة ويب دون كتابة سطر واحد من كود HTML. تقوم هذه الأدوات تلقائيًا بإنشاء كود HTML لتصميم الصفحة الذي يتم إجراؤه باستخدام الماوس وعناصر التحكم المحددة مسبقًا. وبالتالي، يمكن إدراج (باستخدام الماوس) جدول في الصفحة، ثم الاطلاع على كود HTML الذي أنشأه البرنامج لمعرفة العلامات التي يجب استخدامها لتعريف جدول في صفحة ويب. الأمر ليس أكثر تعقيدًا من ذلك. من ناحية أخرى، فإن معرفة لغة HTML أمر لا غنى عنه، حيث يتعين على تطبيقات الويب الديناميكية أن تولد بنفسها الكود HTML لإرساله إلى عملاء الويب. يتم إنشاء هذا الكود برمجيًا، ومن الضروري بالطبع معرفة ما يجب إنشاؤه حتى يحصل العميل على صفحة الويب التي يرغب فيها.
باختصار، ليس هناك حاجة لمعرفة لغة HTML بالكامل لبدء البرمجة على الويب. ومع ذلك، فإن هذه المعرفة ضرورية ويمكن اكتسابها من خلال استخدام برامج إنشاء صفحات الويب مثل Word وFrontPage وDreamWeaver وعشرات البرامج الأخرى. هناك طريقة أخرى لاكتشاف خفايا لغة HTML، وهي تصفح الويب وعرض الكود المصدري للصفحات التي تتميز بخصائص مثيرة للاهتمام وما زالت غير معروفة بالنسبة لك.
2.8.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 سمات>...</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">: يشير إلى أن الصورة التي يجب أن تُستخدم كخلفية للصفحة موجودة في URL /images/standard.jpg على خادم الويب. في سياق مثالنا هذا، سيطلب المتصفح العنوان URL 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.8.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.8.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.8.1.3. حقل إدخال متعدد الأسطر
![]()
<textarea rows="2" name="areaSaisie" cols="20"> ligne1 ligne2 ligne3 </textarea> |
<textarea ...>نص</textarea> يعرض منطقة إدخال متعددة الأسطر تحتوي في البداية على نص | |
rows="2": عدد الأسطر cols="'20": عدد الأعمدة name="areaSaisie": اسم عنصر التحكم |
2.8.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.8.1.5. مربعات الاختيار
<input type="checkbox" name="C1" value="واحد">1 <input type="checkbox" name="C2" value="اثنان" checked>2 <input type="checkbox" name="C3" value="ثلاثة">3 |
![]()
<input type="checkbox" attribut2="valeur2" ....>نص يعرض مربع اختيار مع نص بجانبه. | |
name="C1": اسم عنصر التحكم. يمكن أن تحمل مربعات الاختيار نفس الاسم أو لا. تشكل المربعات التي تحمل نفس الاسم مجموعة من المربعات المرتبطة ببعضها. value="القيمة" : القيمة المخصصة لمربع الاختيار. لا ينبغي الخلط بين هذه القيمة والنص المعروض بجانب زر الاختيار. فهذا النص مخصص للعرض فقط. checked: إذا كانت هذه الكلمة الرئيسية موجودة، فإن زر الاختيار يكون محددًا، وإلا فإنه غير محدد. |
2.8.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.8.1.7. قائمة ذات اختيار واحد
<select size="3" name="lst1"> <option selected>القائمة 1</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.8.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.8.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="دالة(val1, val2,...)" في مثالنا، يؤدي النقر على الزر Effacer إلى استدعاء دالة جافا سكريبت effacer التالية: تعرض الدالة effacer رسالةً تقول: ![]() |
2.8.1.10. زر من نوع «إرسال»
<input type="submit" value="إرسال" name="cmdRenvoyer"> |
![]()
<input type="submit" value="إرسال" name="cmdRenvoyer"> | |
type="submit": يحدد الزر على أنه زر لإرسال بيانات النموذج إلى خادم الويب. عندما ينقر العميل على هذا الزر، سيقوم المتصفح بإرسال بيانات النموذج إلى URL المحددة في سمة action لعلامة <form> وفقًا للطريقة المحددة بواسطة سمة method لنفس العلامة. value="إرسال": النص المعروض على الزر |
2.8.1.11. زر من نوع reset
<input type="reset" value="إعادة الضبط" name="cmdRétablir"> |
![]()
<input type="reset" value="إعادة الضبط" name="cmdRétablir"> | |
type="reset": يحدد الزر على أنه زر إعادة تعيين النموذج. عندما ينقر العميل على هذا الزر، سيعيد المتصفح النموذج إلى الحالة التي استلمه بها. value="إعادة الضبط" : النص المعروض على الزر |
2.8.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.8.2. إرسال قيم نموذج من عميل ويب إلى خادم ويب
ذكرنا في الدراسة السابقة أن عميل الويب لديه طريقتان لإرسال قيم نموذج قام بعرضه إلى خادم الويب: الطريقتان GET و POST. لنرى من خلال مثال الفرق بين الطريقتين. نستأنف المثال السابق ونعالجه بالطريقة التالية:
- يطلب متصفحًّا نموذج URL الوارد في المثال من خادم الويب
- بمجرد الحصول على النموذج، نقوم بتعبئته
- قبل إرسال قيم النموذج إلى خادم الويب بالنقر على الزر Envoyer من النوع submit، نقوم بإيقاف خادم الويب واستبداله بخادم TCP العام الذي سبق استخدامه سابقًا. تجدر الإشارة إلى أن هذا الخادم يعرض على الشاشة أسطر النص التي يرسلها إليه عميل الويب. وبذلك سنرى بالضبط ما يرسله المتصفح.
يتم ملء النموذج على النحو التالي:

الرمز URL المستخدم في هذا المستند هو:

2.8.2.1. طريقة GET
تم برمجة المستند HTML بحيث يستخدم المتصفح الطريقة GET لإرسال قيم النموذج إلى خادم الويب. ولذلك كتبنا:
نقوم بإيقاف تشغيل خادم الويب وتشغيل خادمنا العام TCP على المنفذ 81:
E:\data\serge\JAVA\SOCKETS\serveur générique>java serveurTCPgenerique 81
Serveur générique lancé sur le port 81
الآن، نعود إلى متصفحنا لإرسال بيانات النموذج إلى خادم الويب باستخدام الزر Envoyer:

إليك ما يتلقاه الخادم العام TCP:
<-- GET /html/balises.htm?R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecret&area
Saisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&
cmdRenvoyer=Envoyer&secret=uneValeur HTTP/1.1
<-- Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd
.ms-powerpoint, application/vnd.ms-excel, */*
<-- Referer: http://localhost:81/html/balises.htm
<-- Accept-Language: fr
<-- Accept-Encoding: gzip, deflate
<-- User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705)
<-- Host: localhost:81
<-- Connection: Keep-Alive
<--
كل شيء موجود في الرأس الأول HTTP الذي أرسله المتصفح:
<-- GET /html/balises.htm?R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecret&area
Saisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&
cmdRenvoyer=Envoyer&secret=uneValeur HTTP/1.1
نلاحظ أنه أكثر تعقيدًا بكثير مما صادفناه حتى الآن. نجد فيه بناء الجملة GET URL HTTP/1.1 ولكن في شكل خاص GET URL?param1=القيمة1¶m2=القيمة2&... HTTP/1.1 حيث تمثل parami أسماء عناصر التحكم في نموذج الويب، و«القيم» هي القيم المرتبطة بها. دعونا ندرسها عن كثب. نقدم أدناه جدولًا مكونًا من ثلاثة أعمدة:
- العمود 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>القائمة 1</option> <option>القائمة 2</option> <option>القائمة 3</option> <option>القائمة 4</option> <option>القائمة 5</option> </select> | ![]() | lst1=القائمة 3 - القيمة التي اختارها المستخدم من قائمة الاختيار الفردي |
<select size="3" name="lst2" multiple> <option selected>القائمة 1</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 للحقل المخفي |
لنكرر نفس العملية، ولكن هذه المرة مع ترك الخادم الإلكتروني يقوم بإعداد الرد، ولنرى ما هو هذا الرد. الصفحة التي أرسلها الخادم الإلكتروني هي التالية:

وهي بالضبط نفس الصفحة التي تم استلامها في البداية قبل ملء النموذج. لفهم السبب، يجب إعادة النظر في الطلب URL الذي يطلبه المتصفح عندما يضغط المستخدم على الزر Envoyer:
<-- GET /html/balises.htm?R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecret&area
Saisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&
cmdRenvoyer=Envoyer&secret=uneValeur HTTP/1.1
القيمة المطلوبة هي /html/balises.htm. كما يتم تمرير قيم النموذج إلى هذه القيمة. في الوقت الحالي، لا تستخدم صفحة /html/balises.htm، وهي صفحة ثابتة، هذه القيم. وبالتالي، فإن الصفحة السابقة /html/GET تعادل
ولهذا السبب أعاد الخادم إلينا الصفحة الأصلية مرة أخرى. وتجدر الإشارة إلى أن المتصفح يعرض بالفعل الرابط الكامل URL الذي تم طلبه:

2.8.2.2. الطريقة POST
تم برمجة المستند HTML بحيث يستخدم المتصفح الآن الطريقة POST لإرسال قيم النموذج إلى خادم الويب:
نقوم بإيقاف خادم الويب وتشغيل الخادم العام TCP (الذي سبق أن تناولناه ولكن تم تعديله قليلاً لهذه المناسبة) على المنفذ 81:
E:\data\serge\JAVA\SOCKETS\serveur générique>java serveurTCPgenerique2 81
Serveur générique lancé sur le port 81
الآن، نعود إلى متصفحنا لإرسال بيانات النموذج إلى خادم الويب باستخدام زر «إرسال»:

إليكم ما يتلقاه الخادم العام TCP:
<-- POST /html/balises.htm HTTP/1.1
<-- Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd
.ms-powerpoint, application/vnd.ms-excel, */*
<-- Referer: http://localhost:81/html/balises.htm
<-- Accept-Language: fr
<-- Content-Type: application/x-www-form-urlencoded
<-- Accept-Encoding: gzip, deflate
<-- User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705)
<-- Host: localhost:81
<-- Content-Length: 210
<-- Connection: Keep-Alive
<-- Cache-Control: no-cache
<--
<-- 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 هو GET بل أصبح POST. صيغة الطلب هي POST URL HTTP/1.1، حيث يمثل URL الرأس الذي طلبه المتصفح. وفي الوقت نفسه، يشير POST إلى أن المتصفح لديه بيانات ليرسلها إلى الخادم.
- تشير السطر Content-Type: application/x-www-form-urlencoded إلى نوع البيانات التي سيرسلها المتصفح. وهي بيانات نموذج (x-www-form) مشفرة (urlencoded). يؤدي هذا التشفير إلى تحويل بعض أحرف البيانات المرسلة لتجنب حدوث أخطاء في تفسيرها من قبل الخادم. وبالتالي، يتم استبدال المسافة بعلامة +، وعلامة نهاية السطر بعلامة %OD%OA،... بشكل عام، يتم تحويل جميع الأحرف الموجودة في البيانات والتي قد يؤدي تفسيرها إلى أخطاء من قبل الخادم (&، +، %، ...) إلى %XX حيث يمثل XX الرمز السداسي العشري لكل حرف.
- تشير السطر Content-Length: 210 إلى الخادم بعدد الأحرف التي سيرسلها العميل إليه بمجرد انتهاء الرؤوس HTTP، c.a.d، بعد السطر الفارغ الذي يشير إلى نهاية الرؤوس.
- البيانات (210 حرفًا): R1=نعم&C1=واحد&C2=اثنان&txtSaisie=برمجة+الويب&txtMdp=هذا_سر&areaSaisie=أساسيات+القواعد%0D%0أساسيات+برمجة+الويب&cmbValeurs=الخيار3&lst1=القائمة3&lst2=القائمة1&lst2=القائمة3&cmdRenvoyer=إرسال&secret=uneValeur
نلاحظ أن البيانات المرسلة بواسطة POST هي بنفس تنسيق البيانات المرسلة بواسطة GET.
هل هناك طريقة أفضل من الأخرى؟ لقد رأينا أنه إذا تم إرسال قيم نموذج ما بواسطة المتصفح باستخدام الطريقة GET، فإن المتصفح يعرض في حقل Adresse الخاص به القيمة المطلوبة URL بالصيغة URL?param1=val1¶m2=val2&.... ويمكن النظر إلى ذلك على أنه ميزة أو عيب:
- ميزة إذا أردنا السماح للمستخدم بإضافة رابط URL المُعدّ بهذه المعلمات إلى قائمة الروابط المفضلة لديه
- وهي عيب إذا كنا لا نرغب في أن يتمكن المستخدم من الوصول إلى بعض المعلومات الواردة في النموذج، مثل الحقول المخفية على سبيل المثال
وبالتالي، سنستخدم طريقة POST بشكل حصري تقريبًا في نماذجنا.
2.8.2.3. استرداد قيم نموذج ويب
لا يمكن بأي حال من الأحوال لصفحة ثابتة يُطلب عرضها من قبل عميل يرسل مع ذلك معلمات عبر POST أو GET أن تسترد هذه المعلمات. لا يمكن ذلك إلا لبرنامج، وهو الذي سيتولى عندئذٍ إنشاء استجابة للعميل، وهي استجابة ستكون ديناميكية وتعتمد عمومًا على المعلمات المستلمة. هذا هو مجال برمجة الويب، وهو مجال سنتناوله بمزيد من التفصيل في الفصل التالي مع عرض تقنيات برمجة الويب باستخدام لغة Java: السيرفلتات (servlets) وصفحات JSP.







