Skip to content

2. الأساسيات

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

2.1. مكونات تطبيق الويب

رقم
الدور
أمثلة شائعة
1
OS الخادم
Linux، Windows
2
خادم الويب
أباتشي (لينكس، ويندوز)
IIS (NTPWS (Win9x)
3
نصوص برمجية تُنفَّذ على جانب الخادم. ويمكن تنفيذها بواسطة وحدات
الخادم أو بواسطة برامج خارجية (CGI).
PERL (Apache، IIS، PWS)
VBSCRIPT (IIS، PWS)
JAVASCRIPT (IIS، PWS)
PHP (Apache، IIS، PWS)
JAVA (Apache، IIS، PWS)
C#، VB.NET (IIS)
4
قاعدة البيانات - يمكن أن تكون موجودة على نفس الجهاز
الذي يستخدمها أو على جهاز آخر عبر الإنترنت.
Oracle (Linux، Windows)
MySQL (Linux، Windows)
Access (ويندوز)
SQL Server (ويندوز)
5
OS العميل
لينكس، ويندوز
6
متصفح الويب
نتسكيب، إنترنت إكسبلورر
7
نصوص برمجية تُنفَّذ من جانب العميل داخل المتصفح.
لا تتمتع هذه البرامج النصية بأي وصول إلى أقراص جهاز العميل.
VBscript (IE)
جافا سكريبت (IE، نيتسكيب)
PerlScript (IE)
التطبيقات الصغيرة JAVA

2.2. تبادل البيانات في تطبيق ويب باستخدام نموذج

رقم
الدور
1
يطلب المتصفح URL للمرة الأولى (http://machine/url). لم يتم تمرير أي معلمات.
2
يرسل خادم الويب إليه صفحة الويب الخاصة بـ URL. قد تكون هذه الصفحة ثابتة أو مُنشأة ديناميكيًا بواسطة برنامج نصي على الخادم (SA) الذي قد يكون استخدم محتوى قواعد البيانات (SB، SC). في هذه الحالة، سيكتشف البرنامج النصي أن URL قد طُلبت دون تمرير أي معلمات، وسيقوم بإنشاء الصفحة الأولية WEB.
يتلقى المتصفح الصفحة ويعرضها (CA). وقد تمكنت البرامج النصية على جانب المتصفح (CB) من تعديل الصفحة الأولية التي أرسلها الخادم. بعد ذلك، من خلال التفاعلات بين المستخدم (CD) والبرامج النصية (CB)، سيتم تعديل صفحة الويب. سيتم ملء النماذج على وجه الخصوص.
3
يقوم المستخدم بالتحقق من صحة بيانات النموذج التي يجب إرسالها بعد ذلك إلى خادم الويب. يقوم المتصفح بإعادة طلب URL الأصلي أو غيره حسب الحالة، ويقوم في الوقت نفسه بإرسال قيم النموذج إلى الخادم. ويمكنه استخدام طريقتين لهذا الغرض، هما GET و POST. عند استلام الطلب من العميل، يقوم الخادم بتشغيل البرنامج النصي (SA) المرتبط بـ URL المطلوب، وهو البرنامج النصي الذي سيقوم باكتشاف المعلمات ومعالجتها.
4
يقدم الخادم الصفحة WEB التي تم إنشاؤها بواسطة البرنامج (SA، SB، SC). هذه الخطوة مطابقة للخطوة 2 السابقة. تتم عمليات التبادل الآن وفقًا للخطوتين 2 و3.

2.3. بعض الموارد

فيما يلي قائمة بالموارد التي تتيح تثبيت واستخدام بعض الأدوات اللازمة لتطوير الويب. وتوجد في الملحق إرشادات حول كيفية تثبيت هذه الأدوات.

Serveur Apache
- Apache، التثبيت والتشغيل، O'Reilly
Serveur IIS, PWS
PERL
- البرمجة بلغة بيرل، لاري وول، أورايلي
- تطبيقات CGI بلغة بيرل، نيوس وفرومانز، أورايلي
- الوثائق المرفقة مع Active Perl
PHP
- البرمجة على الويب باستخدام PHP، لاكروا، إيرول
- دليل استخدام PHP المتاح على موقع PHP
VBSCRIPT, ASP
- واجهة بين WEB وقاعدة البيانات تحت WinNT، أليكس هومر، Eyrolles
JAVASCRIPT
HTML
JAVA
- JAVA Servlets، جيسون هانتر، أورايلي
- البرمجة الشبكية باستخدام Java، إليوت روستي هارولد، أورايلي
- JDBC و Java، جورج ريس، أورايلي
Base de données
- دليل MySQL متاح على موقع MySQL
- Oracle 8i على نظام Linux، جيل بريارد، دار إيرول
- Oracle 8i على نظام NT، جيل بريارد، دار إيرول

2.4. الرموز

فيما يلي، سنفترض أن عددًا معينًا من الأدوات قد تم تثبيته وسنستخدم الرموز التالية:

الرمز
المعنى
<apache>
جذر شجرة الخادم Apache
<apache-DocumentRoot>
جذر صفحات الويب التي يقدمها Apache. يجب أن توجد صفحات الويب تحت هذا الجذر. وبالتالي، فإن الرابط URL http://localhost/page1.htm يتوافق مع الملف <apache-DocumentRoot>\page1.htm.
<apache-cgi-bin>
جذر الشجرة المرتبط بالاسم المستعار cgi-bin، حيث يمكن وضع البرامج النصية CGI الخاصة بـ Apache. وبالتالي، فإن URL http://localhost/cgi-bin/test1.pl يتوافق مع الملف <apache-cgi-bin>\test1.pl.
<pws-DocumentRoot>
جذر صفحات الويب التي يقدمها PWS. يجب أن توجد صفحات الويب ضمن هذا المجلد الجذري. وبالتالي، فإن URL http://localhost/page1.htm يتوافق مع الملف <pws-DocumentRoot>\page1.htm.
<perl>
جذر شجرة لغة Perl. عادةً ما يوجد الملف القابل للتنفيذ perl.exe في <perl>\bin.
<php>
جذر شجرة لغة PHP. عادةً ما يوجد الملف القابل للتنفيذ php.exe في <php>.
<java>
جذر شجرة جافا. توجد الملفات التنفيذية المرتبطة بجافا في <java>\bin.
<tomcat>
جذر خادم 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>

الذي ينتج الصفحة التالية:

الاختبارات

Image

test1

  • تشغيل خادم Apache
  • وضع البرنامج النصي essai1.html في <apache-DocumentRoot>
  • عرض ملف URL http://localhost/essai1.html باستخدام متصفح
  • إيقاف خادم Apache

اختبار 2

  • تشغيل خادم 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>

ينتج الصفحة التالية:

Image

الاختبار

  • تشغيل الخادم PWS
  • وضع البرنامج النصي essai2.asp في <pws-DocumentRoot>
  • الوصول إلى 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. يجب تعديله إذا لزم الأمر. بمجرد تنفيذه بواسطة خادم ويب، يُنتج البرنامج النصي الصفحة التالية:

Image

اختبار

  • خادم الويب: 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 (الصفحة الرئيسية الشخصية، معالج 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>

ينتج البرنامج النصي السابق الصفحة التالية:

الاختبارات

Image

Image

  • راجع ملف التكوين srm.conf أو httpd.conf الخاص بـ Apache في <Apache>\confs

  • للعلم، تحقق من أسطر التكوين في ملف php

test1

test2

  • تشغيل الخادم PWS

  • للعلم، التحقق من إعدادات PWS فيما يتعلق بـ php

  • وضع essai4.php في <pws-DocumentRoot>\php

  • طلب URL http://localhost/essai4.php

2.5.5. نص برمجي JSP (صفحات خادم Java)

البرنامج النصي heure.jsp

<%  //programme Java affichant l'heure %>

<%@ page import="java.util.*" %>

<% 
     // code JAVA pour calculer l'heure
  Calendar calendrier=Calendar.getInstance();
  int heures=calendrier.get(Calendar.HOUR_OF_DAY);
  int minutes=calendrier.get(Calendar.MINUTE);
  int secondes=calendrier.get(Calendar.SECOND);
   // heures, minutes, secondes sont des variables globales
   // qui pourront être utilisées dans le code HTML
%>

<% // code 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>

بمجرد تنفيذه بواسطة خادم الويب، يُنتج هذا البرنامج النصي الصفحة التالية:

Image

الاختبارات

  • ضع البرنامج النصي 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 التالي:

         <input type="button" value="OK" name="cmdOK" onclick="reagir">

تشير السمة onclick إلى اسم الدالة التي سيتم استدعاؤها عندما ينقر المستخدم على الزر OK. عندما يقوم المتصفح بتحميل هذه الصفحة وينقر المستخدم على الزر OK، ستظهر الصفحة التالية:

Image

الاختبارات

المتصفح IE هو الوحيد القادر على تنفيذ البرامج النصية VBScript. أما متصفح Netscape فيحتاج إلى ملحقات برمجية للقيام بذلك. يمكن إجراء الاختبارات التالية:

اختبار 1

  • خادم Apache
  • نص برمجي vbs1.html في <apache-DocumentRoot>
  • طلب عنوان URL http://localhost/vbs1.html باستخدام متصفح IE

الاختبار 2

  • خادم PWS
  • البرنامج النصي vbs1.html في <pws-DocumentRoot>
  • طلب عنوان URL 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 ونتسكيب. ويؤدي تنفيذها إلى نفس النتائج:

Image

الاختبارات

test1

  • خادم Apache
  • نص برمجي js1.html في <apache-DocumentRoot>
  • اطلب الرابط http://localhost/js1.html باستخدام متصفح IE أو Netscape

الاختبار 2

  • خادم PWS
  • النص البرمجي js1.html في <pws-DocumentRoot>
  • اطلب الرابط http://localhost/js1.html باستخدام متصفح IE أو Netscape

2.7. التبادلات بين العميل والخادم

لنعد إلى مخططنا الأولي الذي يوضح العناصر الفاعلة في تطبيق ويب:

نركز هنا على التبادلات بين جهاز العميل وجهاز الخادم. تتم هذه التبادلات عبر شبكة، ومن الجيد تذكير البنية العامة للتبادلات بين جهازين بعيدين.

2.7.1. نموذج OSI

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

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

في كل طبقة، تقوم العملية المرسلة المكلفة بإرسال المعلومات بإرسالها إلى عملية مستقبلة على الجهاز الآخر الذي ينتمي إلى نفس الطبقة التي تنتمي إليها. وتقوم بذلك وفقًا لقواعد معينة تُسمى بروتوكول الطبقة. وبذلك نحصل على مخطط الاتصال النهائي التالي:

دور الطبقات المختلفة هو كما يلي:

Physique
تضمن نقل البتات عبر وسيط مادي. يوجد في هذه الطبقة معدات طرفية لمعالجة البيانات (E.T.T.D.) مثل المحطة الطرفية أو الكمبيوتر، بالإضافة إلى معدات إنهاء دوائر البيانات (E.T.C.D.) مثل المُعدِّل/المُفكِّك، والمُضاعِف، والمُركِّز. النقاط المهمة في هذا المستوى هي:
. اختيار ترميز المعلومات (تناظري أو رقمي)
. اختيار طريقة الإرسال (متزامنة أو غير متزامنة).
Liaison de données
يخفي الخصائص الفيزيائية للطبقة الفيزيائية. يكتشف أخطاء الإرسال ويصححها.
Réseau
يدير المسار الذي يجب أن تسلكه المعلومات المرسلة عبر الشبكة. ويُطلق على ذلك اسم routage: تحديد المسار الذي يجب أن تسلكه المعلومات حتى تصل إلى مستلمها.
Transport
يسمح بالاتصال بين تطبيقين في حين أن الطبقات السابقة كانت تسمح فقط بالاتصال بين الأجهزة. قد تكون إحدى الخدمات التي توفرها هذه الطبقة هي التعدد: يمكن لطبقة النقل استخدام نفس اتصال الشبكة (من جهاز إلى جهاز) لنقل المعلومات الخاصة بعدة تطبيقات.
Session
نجد في هذه الطبقة خدمات تسمح لأحد التطبيقات بفتح جلسة عمل والحفاظ عليها على جهاز بعيد.
Présentation
وتهدف هذه الطبقة إلى توحيد عرض البيانات على الأجهزة المختلفة. وبالتالي، فإن البيانات الواردة من الجهاز «أ» سيتم «تنسيقها» بواسطة طبقة Présentation الخاصة بالجهاز «أ»، وفقًا لتنسيق قياسي قبل إرسالها عبر الشبكة. وعند وصولها إلى الطبقة Présentation في الجهاز المستلم B، الذي سيتعرف عليها بفضل تنسيقها القياسي، سيتم تكييفها بطريقة أخرى حتى يتعرف عليها تطبيق الجهاز B.
Application
في هذه المرحلة، نجد التطبيقات التي عادةً ما تكون قريبة من المستخدم، مثل البريد الإلكتروني أو نقل الملفات.

2.7.2. النموذج TCP/IP

يُعد النموذج OSI نموذجًا مثاليًّا. وتقترب مجموعة البروتوكولات TCP/IP منه بالشكل التالي:

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

توجد تطبيقات الويب في الطبقة Application، وبالتالي فهي تعتمد على بروتوكولات TCP-IP. تتبادل طبقات Application الخاصة بأجهزة العملاء والخادم الرسائل التي تُعهد بها إلى الطبقات من 1 إلى 4 في النموذج لتوجيهها إلى وجهتها. لكي تتفاهم الطبقات التطبيقية في كلا الجهازين، يجب أن «تتحدث» نفس اللغة أو البروتوكول. ويُسمى بروتوكول تطبيقات الويب HTTP (بروتوكول النقل HyperText). وهو بروتوكول نصي، c.a.d، حيث تتبادل الأجهزة أسطر نصية عبر الشبكة للتواصل فيما بينها. هذه التبادلات موحدة، بحيث يتوفر للعميل عدد معين من الرسائل للإشارة بدقة إلى ما يريده من الخادم، كما يتوفر للخادم أيضًا عدد معين من الرسائل لتقديم ردّه إلى العميل. ويأخذ تبادل الرسائل هذا الشكل التالي:

العميل --> الخادم

عندما يوجه العميل طلبه إلى خادم الويب، فإنه يرسل

  1. أسطر نصية بتنسيق HTTP للإشارة إلى ما يريده
  1. سطر فارغ
  2. وثيقة (اختياري)

الخادم --> العميل

عندما يرد الخادم على العميل، فإنه يرسل

  1. سطور نصية بتنسيق HTTP للإشارة إلى ما يرسله
  2. سطر فارغ
  3. اختياريًا مستند

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

  1. يتصل المتصفح بخادم الويب ويطلب الصفحة التي يرغب فيها. يتم تحديد الموارد المطلوبة بشكل فريد بواسطة URL (محدد موقع الموارد الموحد). لا يرسل المتصفح سوى رؤوس HTTP ولا يرسل أي مستند.
  2. يرد عليه الخادم. فيقوم أولاً بإرسال رؤوس HTTP تشير إلى نوع الرد الذي يرسله. وقد يكون هذا خطأً إذا كانت الصفحة المطلوبة غير موجودة. وإذا كانت الصفحة موجودة، فسيشير الخادم في رؤوس الاستجابة HTTP إلى أنه سيقوم بعد ذلك بإرسال مستند HTML (لغة الترميز HyperText). هذا المستند عبارة عن سلسلة من أسطر النص بتنسيق HTML. يحتوي النص HTML على علامات (علامات ترميز) تزود المتصفح بتوجيهات حول كيفية عرض النص.
  3. يعرف العميل من خلال رؤوس HTTP الصادرة عن الخادم أنه سيتلقى مستندًا بتنسيق HTML. سيقوم بتحليل هذا المستند وربما يلاحظ أنه يحتوي على إحالات إلى صور. هذه الصور غير موجودة في المستند HTML. لذا، يقوم بإرسال طلب جديد إلى نفس خادم الويب لطلب الصورة الأولى التي يحتاجها. هذا الطلب مطابق للطلب الذي تم إرساله في الخطوة 1، باستثناء أن المورد المطلوب مختلف. سيقوم الخادم بمعالجة هذا الطلب عن طريق إرسال الصورة المطلوبة إلى العميل. هذه المرة، ستوضح رؤوس HTTP في الرد أن المستند المرسل هو صورة وليس مستند HTML.
  4. يستلم العميل الصورة المرسلة. ستتكرر الخطوتان 3 و4 حتى يحصل العميل (وهو متصفح في العادة) على جميع المستندات التي تسمح له بعرض الصفحة بالكامل.

2.7.3. بروتوكول HTTP

لنكتشف بروتوكول HTTP من خلال أمثلة. ما الذي يتبادله المتصفح وخادم الويب؟

2.7.3.1. استجابة خادم HTTP

سنكتشف هنا كيف يستجيب خادم الويب لطلبات عملائه. خدمة الويب أو خدمة HTTP هي خدمة TCP-IP تعمل عادةً على المنفذ 80. وقد تعمل على منفذ آخر. في هذه الحالة، سيضطر متصفح العميل إلى تحديد هذا المنفذ في عنوان URL الذي يطلبه. يتخذ عنوان URL الشكل العام التالي:

protocole://machine[:port]/chemin/infos

مع

بروتوكول
http لخدمة الويب. يمكن للمتصفح أيضًا أن يعمل كعميل لخدمات ftp و news و telnet، ...
الجهاز
اسم الجهاز الذي تعمل عليه خدمة الويب
المنفذ
منفذ خدمة الويب. إذا كان الرقم 80، فيمكن حذف رقم المنفذ. وهذا هو الحال الأكثر شيوعًا
المسار
المسار الذي يشير إلى المورد المطلوب
المعلومات
معلومات إضافية تُقدم إلى الخادم لتوضيح طلب العميل

ماذا يفعل المتصفح عندما يطلب المستخدم تحميل ملف URL؟

  1. يفتح اتصالاً TCP-IP مع الجهاز والمنفذ المحددين في الجزء machine[:port] من URL. إن فتح اتصال TCP-IP يعني إنشاء «قناة» اتصال بين جهازين. وبمجرد إنشاء هذه القناة، ستمر جميع المعلومات المتبادلة بين الجهازين عبرها. لا يتضمن إنشاء هذا القناة TCP-IP بروتوكول الويب HTTP بعد.
  2. بعد إنشاء القناة TCP-IP، سيقوم العميل بتوجيه طلبه إلى خادم الويب عن طريق إرسال أسطر نصية (أوامر) بتنسيق HTTP. سيقوم بإرسال جزء المسار/المعلومات من URL إلى الخادم
  3. سيرد عليه الخادم بنفس الطريقة وعبر نفس القناة
  4. سيتخذ أحد الطرفين قرار إغلاق القناة. ويعتمد ذلك على بروتوكول HTTP المستخدم. مع بروتوكول HTTP 1.0، يقوم الخادم بإغلاق الاتصال بعد كل رد من ردوده. وهذا يجبر العميل الذي يحتاج إلى إرسال عدة طلبات للحصول على المستندات المختلفة المكونة لصفحة ويب على فتح اتصال جديد مع كل طلب، وهو ما ينطوي على تكلفة. مع بروتوكول HTTP/1.1، يمكن للعميل أن يطلب من الخادم إبقاء الاتصال مفتوحًا حتى يطلب منه إغلاقه. وبالتالي، يمكنه استرداد جميع المستندات الخاصة بصفحة ويب عبر اتصال واحد وإغلاق الاتصال بنفسه بمجرد الحصول على آخر مستند. سيكتشف الخادم هذا الإغلاق ويقوم هو أيضًا بإغلاق الاتصال.

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

java clientTCPgenerique machine port

مع

machine
اسم الجهاز الذي تعمل عليه الخدمة المراد الاتصال بها
المنفذ
المنفذ الذي يتم تقديم الخدمة من خلاله

باستخدام هاتين المعلومتين، سيقوم البرنامج بفتح اتصال TCP-IP مع الجهاز والمنفذ المحددين. سيُستخدم هذا الاتصال لتبادل أسطر النص بين العميل وخادم الويب. يكتب المستخدم سطور العميل على لوحة المفاتيح ويتم إرسالها إلى الخادم. أما سطور النص التي يرسلها الخادم كرد، فتُعرض على الشاشة. وبذلك يمكن إقامة حوار مباشر بين المستخدم الذي يستخدم لوحة المفاتيح وخادم الويب. لنجرب ذلك على الأمثلة التي سبق عرضها. كنا قد أنشأنا الصفحة الثابتة التالية: HTML:


<html>
  <head>
    <title>essai 1 : une page statique</title>
   </head>
   <body>
     <center>
     <h1>Une page statique...</h1>
   </body>
</html>

التي نعرضها في متصفح:

Image

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

Image

الآن دعونا نستخدم عميلنا العام 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. تجدر الإشارة إلى أن هذا التبادل يتكون من ثلاثة عناصر:

  1. رؤوس HTTP
  2. سطر فارغ
  3. بيانات اختيارية

في مثالنا، لا يرسل العميل سوى طلب واحد:

GET /essais/essai1.html HTTP/1.0

يتكون هذا السطر من ثلاثة مكونات:

GET
الأمر HTTP لطلب مورد. وهناك أمور أخرى:
HEAD تطلب موردًا ولكنها تقتصر على رؤوس HTTP في استجابة الخادم. ولا يتم إرسال المورد نفسه.
PUT تسمح للعميل بإرسال مستند إلى الخادم
/essais/essai1.html
المورد المطلوب
HTTP/1.0
مستوى بروتوكول 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
<--
HTTP/1.1 200 OK
يقول الخادم
  • أنه يدعم بروتوكول HTTP الإصدار 1.1
  • وأنه يمتلك المورد المطلوب (الرمز 200، الرسالة OK)
Date: ...
تاريخ/وقت الرد
Server: 
يحدد الخادم هويته. في هذه الحالة، هو خادم Apache
Last-Modified:
تاريخ آخر تعديل للمورد الذي طلبه العميل
ETag:
...
Accept-Ranges: bytes
وحدة قياس البيانات المرسلة. هنا البايت (byte)
Content-Length: 161
عدد البايتات في المستند الذي سيتم إرساله بعد الرؤوس HTTP. هذا الرقم هو في الواقع حجم الملف بالبايت essai1.html:
E:\data\serge\web\essais>dir essai1.html

08/07/2002  10:00                  161 essai1.html
Connection: close
يقول الخادم إنه سيغلق الاتصال بمجرد إرسال المستند
Content-type: text/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 الذي تم إنشاؤه في البداية. إذا كان عميلنا متصفحًا، فسيقوم، بعد استلام هذه الأسطر النصية، بتفسيرها لعرض الصفحة التالية للمستخدم عبر لوحة المفاتيح:

Image

لنستخدم مرة أخرى عميلنا العام 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. أولاً باستخدام متصفح:

Image

يبلغ حجم الملف univ01.gif 3167 بايت:

E:\data\serge\web\images>dir univ01.gif
14/04/2000  13:37                3 167 univ01.gif

لنستخدم الآن العميل العام 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
<--

يجب ملاحظة النقاط التالية في استجابة الخادم:

HEAD
  • نحن نطلب فقط رؤوس الموارد HTTP. في الواقع، الصورة هي ملف ثنائي وليست ملفًا نصيًّا، وعرضها على الشاشة كنص لا ينتج عنه أي شيء قابل للقراءة.
Content-Length: 3167
  • هذا هو حجم الملف univ01.gif
Content-Type: image/gif
  • يُعلم الخادم عميله بأنه سيرسل له مستندًا من النوع image/gif، c.a.d. صورة بتنسيق GIF. لو كانت الصورة بتنسيق JPEG، لكان نوع المستند هو image/jpeg. أنواع المستندات موحدة وتُسمى أنواع MIME (Multi-purpose Mail Internet Extension).

2.7.3.2. طلب عميل HTTP

الآن، لنطرح السؤال التالي: إذا أردنا كتابة برنامج «يتواصل» مع خادم ويب، فما هي الأوامر التي يجب أن يرسلها إلى خادم الويب للحصول على مورد معين؟ لقد حصلنا في الأمثلة السابقة على بداية إجابة. وقد صادفنا ثلاثة أوامر:

GET ressource protocole
  • لطلب مورد معين وفقًا لإصدار معين من البروتوكول HTTP. يرسل الخادم استجابة بتنسيق HTTP متبوعة بسطر فارغ ثم المورد المطلوب
HEAD ressource protocole
  • وكذلك الأمر هنا، إلا أن الرد يقتصر على الرؤوس HTTP والسطر الفارغ
host: machine:port
  • لتحديد (بروتوكول HTTP 1.1) الجهاز والمنفذ الخاص بخادم الويب الذي تم الاستعلام عنه

هناك أوامر أخرى. لاكتشافها، سنستخدم الآن خادمًا عامًا 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:

Image

لنلقِ الآن نظرة على نافذة الخادم التي تعرض ما أرسله العميل إليه (تم حذف بعض الأسطر الخاصة بتشغيل البرنامج 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 التي لم نكن قد صادفناها من قبل:

Accept:
  • قائمة أنواع المستندات MIME التي يستطيع المتصفح معالجتها.
Accept-language:
  • اللغة المفضلة والمقبولة للمستندات.
Accept-Encoding:
  • نوع ترميز المستندات التي يستطيع المتصفح معالجتها
User-Agent:
  • هوية العميل
Connection:
  • Close: سيقوم الخادم بإغلاق الاتصال بعد إرسال الرد
  • Keep-Alive: سيبقى الاتصال مفتوحًا بعد استلام الرد من الخادم. سيسمح ذلك للمتصفح بطلب المستندات الأخرى اللازمة لبناء الصفحة دون الحاجة إلى إعادة إنشاء اتصال.

تنتهي الرؤوس 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>

ثم يعرض المتصفح الصفحة التالية:

Image

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

Image

أي بالضبط ما تم إرساله من الخادم العام.

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 هنا. يعرض هذا المثال بعض العناصر التي يمكن العثور عليها في مستند ويب مثل:

  • جدول
  • صورة
  • رابط

Image

يكون المستند HTML بالشكل العام التالي:

<html>
    <head>
        <title>Un titre</title>
        ...
    </head>
    <body attributs>
        ...
    </body>
</html>

يُحاط المستند بأكمله بعلامتي <html>...</html>. ويتكون من جزأين:

  1. <head>...</head>: هذا هو الجزء غير القابل للعرض من المستند. وهو يوفر معلومات للمتصفح الذي سيقوم بعرض المستند. وغالبًا ما نجد فيه العلامة <title>...</title> التي تحدد النص الذي سيظهر في شريط عنوان المتصفح. وقد نجد فيه علامات أخرى، لا سيما العلامات التي تحدد الكلمات المفتاحية للمستند، وهي الكلمات المفتاحية التي تستخدمها محركات البحث لاحقًا. كما يمكن أن نجد في هذا الجزء نصوصًا برمجية، مكتوبة في الغالب بلغة جافا سكريبت أو في بي سكريبت، والتي سيتم تنفيذها بواسطة المتصفح.
  2. <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
titre du document
<title>balises</title>
balises سيظهر في شريط عنوان المتصفح الذي سيعرض المستند
barre horizontale
<hr>: يعرض خطًا أفقيًا
tableau
<attributes table>....</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")
image
<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 للحصول على الصورة المشار إليها هنا.
lien
<a href="http://istia.univ-angers.fr">هنا</a>: يجعل النص ici بمثابة رابط إلى URL http://istia.univ-angers.fr.
fond de page
<body background="/images/standard.jpg">: يشير إلى أن الصورة التي يجب أن تُستخدم كخلفية للصفحة موجودة في URL /images/standard.jpg على خادم الويب. في سياق مثالنا هذا، سيطلب المتصفح العنوان URL http://localhost:81/images/standard.jpg للحصول على صورة الخلفية هذه.

يتضح من هذا المثال البسيط أنه لإنشاء المستند بالكامل، يتعين على المتصفح إرسال ثلاث طلبات إلى الخادم:

  1. http://localhost:81/html/balises.htm للحصول على المصدر HTML للوثيقة
  2. http://localhost:81/images/univ01.gif للحصول على الصورة univ01.gif
  3. http://localhost:81/images/standard.jpg للحصول على صورة الخلفية standard.jpg

يقدم المثال التالي نموذج ويب تم إنشاؤه أيضًا باستخدام FrontPage.

Image

الرمز HTML الذي تم إنشاؤه بواسطة FrontPage وتم تبسيطه قليلاً هو التالي:

<html>

  <head>
      <title>balises</title>
    <script language="JavaScript">
        function effacer(){
          alert("Vous avez cliqué sur le bouton Effacer");
      }//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
formulaire
<form method="POST" >
champ de saisie
<input type="text" name="txtSaisie" size="20" value="بضع كلمات">
champ de saisie cachée
<input type="password" name="txtMdp" size="20" value="unMotDePasse">
champ de saisie multilignes
<textarea rows="2" name="areaSaisie" cols="20">
السطر 1
السطر 2
السطر 3
</textarea>
boutons radio
<input type="radio" value="نعم" name="R1">نعم
<input type="radio" name="R1" value="لا" checked>لا
cases à cocher
<input type="checkbox" name="C1" value="واحد">1
<input type="checkbox" name="C2" value="اثنان" checked>2
<input type="checkbox" name="C3" value="ثلاثة">3
Combo
<select size="1" name="cmbValeurs">
<option>الخيار 1</option>
<option selected>الخيار 2</option>
<option>الخيار 3</option>
</select>
liste à sélection unique
<select size="3" name="lst1">
<option selected>القائمة 1</option>
<option>القائمة 2</option>
<option>القائمة 3</option>
<option>القائمة 4</option>
<option>القائمة 5</option>
</select>
liste à sélection multiple
<select size="3" name="lst2" multiple>
<option>القائمة 1</option>
<option>القائمة 2</option>
<option selected>القائمة 3</option>
<option>القائمة 4</option>
<option>القائمة 5</option>
</select>
bouton de type submit
<input type="submit" value="إرسال" name="cmdRenvoyer">
bouton de type reset
<input type="reset" value="إعادة الضبط" name="cmdRétablir">
bouton de type button
<input type="button" value="مسح" name="cmdEffacer" onclick="effacer()">

دعونا نستعرض عناصر التحكم المختلفة هذه.

2.8.1.1. النموذج

formulaire
<form method="POST" >
balise HTML
<form name="..." method="..." action="...">...</form>
attributs
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. حقل الإدخال

Image

Image

champ de saisie
<input type="text" name="txtSaisie" size="20" value="بضع كلمات">
<input type="password" name="txtMdp" size="20" value="unMotDePasse">
balise HTML
<input type="..." name="..." size=".." value="..">
توجد علامة input لمختلف عناصر التحكم. والسمة type هي التي تسمح بالتمييز بين عناصر التحكم المختلفة هذه.
attributs
type="text": يحدد أن هذا حقل إدخال
type="password": يتم استبدال الأحرف الموجودة في حقل الإدخال بأحرف *. وهذا هو الفرق الوحيد عن حقل الإدخال العادي. هذا النوع من عناصر التحكم مناسب لإدخال كلمات المرور.
size="20": عدد الأحرف المرئية في الحقل - لا يمنع إدخال المزيد من الأحرف
name="txtSaisie": اسم عنصر التحكم
value="بعض الكلمات": النص الذي سيظهر في حقل الإدخال.

2.8.1.3. حقل إدخال متعدد الأسطر

Image

champ de saisie multilignes
<textarea rows="2" name="areaSaisie" cols="20">
ligne1
ligne2
ligne3
</textarea>
balise HTML
<textarea ...>نص</textarea>
يعرض منطقة إدخال متعددة الأسطر تحتوي في البداية على نص
attributs
rows="2": عدد الأسطر
cols="'20": عدد الأعمدة
name="areaSaisie": اسم عنصر التحكم

2.8.1.4. أزرار الاختيار

Image

boutons radio
<input type="radio" value="نعم" name="R1">نعم
<input type="radio" name="R1" value="لا" checked>لا
balise HTML
<input type="radio" attribut2="valeur2" ....>نص
يعرض زر اختيار مع نص بجانبه.
attributs
name="radio": اسم عنصر التحكم. تشكل أزرار الاختيار التي تحمل الاسم نفسه مجموعة من الأزرار المتنافية: لا يمكن تحديد سوى واحد منها.
value="القيمة" : القيمة المخصصة لزر الاختيار. لا يجب الخلط بين هذه القيمة والنص المعروض بجانب زر الاختيار. فهذا النص مخصص للعرض فقط.
checked: إذا كانت هذه الكلمة المفتاحية موجودة، يكون زر الاختيار محددًا، وإلا فإنه غير محدد.

2.8.1.5. مربعات الاختيار

cases à cocher
<input type="checkbox" name="C1" value="واحد">1
<input type="checkbox" name="C2" value="اثنان" checked>2
<input type="checkbox" name="C3" value="ثلاثة">3

Image

balise HTML
<input type="checkbox" attribut2="valeur2" ....>نص
يعرض مربع اختيار مع نص بجانبه.
attributs
name="C1": اسم عنصر التحكم. يمكن أن تحمل مربعات الاختيار نفس الاسم أو لا. تشكل المربعات التي تحمل نفس الاسم مجموعة من المربعات المرتبطة ببعضها.
value="القيمة" : القيمة المخصصة لمربع الاختيار. لا ينبغي الخلط بين هذه القيمة والنص المعروض بجانب زر الاختيار. فهذا النص مخصص للعرض فقط.
checked: إذا كانت هذه الكلمة الرئيسية موجودة، فإن زر الاختيار يكون محددًا، وإلا فإنه غير محدد.

2.8.1.6. قائمة منسدلة (combo)

Combo
<select size="1" name="cmbValeurs">
<option>choix1</option>
<option selected>الخيار 2</option>
<option>choix3</option>
</select>

Image

balise HTML
<select size=".." name="..">
<option [selected]>...</option>
...
</select>
يعرض في قائمة النصوص الموجودة بين العلامتين <option>...</option>
attributs
name="cmbValeurs": اسم عنصر التحكم.
size="1": عدد عناصر القائمة المرئية. size="1" يجعل القائمة تعادل مربع الاختيار.
selected: إذا كانت هذه الكلمة الرئيسية موجودة لعنصر من عناصر القائمة، فسيظهر هذا العنصر محددًا في القائمة. في المثال أعلاه، يظهر عنصر القائمة choix2 كالعنصر المحدد في مربع الاختيار عند عرضه لأول مرة.

2.8.1.7. قائمة ذات اختيار واحد

liste à sélection unique
<select size="3" name="lst1">
<option selected>liste1</option>
<option>liste2</option>
<option>liste3</option>
<option>liste4</option>
<option>liste5</option>
</select>

Image

balise HTML
<select size=".." name="..">
<option [selected]>...</option>
...
</select>
يعرض في قائمة النصوص الموجودة بين العلامتين <option>...</option>
attributs
وهي نفس العناصر الموجودة في القائمة المنسدلة التي تعرض عنصرًا واحدًا فقط. ولا يختلف هذا العنصر عن القائمة المنسدلة السابقة إلا في سمة size>1.

2.8.1.8. قائمة الاختيار المتعدد

liste à sélection unique
<select size="3" name="lst2" multiple>
<option selected>liste1</option>
<option>liste2</option>
<option selected>القائمة 3</option>
<option>liste4</option>
<option>liste5</option>
</select>

Image

balise HTML
<select size=".." name=".." multiple>
<option [selected]>...</option>
...
</select>
يعرض في قائمة النصوص الموجودة بين العلامتين <option>...</option>
attributs
متعدد: يتيح تحديد عدة عناصر من القائمة. في المثال أعلاه، تم تحديد العنصرين liste1 و liste3 معًا.

2.8.1.9. زر من النوع button

bouton de type button
<input type="button" value="مسح" name="cmdEffacer" onclick="effacer()">

Image

balise HTML
<input type="button" value="..." name="..." onclick="effacer()" ....>
attributs
type="button": يحدد عنصر تحكم زر. يوجد نوعان آخران من الأزرار، وهما submit و reset.
value="حذف" : النص المعروض على الزر
onclick="وظيفة()" : يسمح بتعريف وظيفة يتم تنفيذها عندما ينقر المستخدم على الزر. هذه الوظيفة جزء من البرامج النصية المحددة في المستند الويب المعروض. الصيغة السابقة هي صيغة javascript. إذا كانت البرامج النصية مكتوبة بلغة vbscript، فيجب كتابة onclick="وظيفة" بدون الأقواس. وتصبح الصيغة مماثلة إذا كان من الضروري تمرير معلمات إلى الدالة: onclick="dالة(val1, val2,...)"
في مثالنا، يؤدي النقر على الزر Effacer إلى استدعاء دالة جافا سكريبت effacer التالية:
    <script language="JavaScript">
        function effacer(){
          alert("Vous avez cliqué sur le bouton Effacer");
      }//effacer
        </script>
تعرض الدالة effacer رسالة:

2.8.1.10. زر من نوع «إرسال»

bouton de type submit
<input type="submit" value="إرسال" name="cmdRenvoyer">

Image

balise HTML
<input type="submit" value="إرسال" name="cmdRenvoyer">
attributs
type="submit": يحدد الزر على أنه زر لإرسال بيانات النموذج إلى خادم الويب. عندما ينقر العميل على هذا الزر، سيقوم المتصفح بإرسال بيانات النموذج إلى URL المحددة في سمة action لعلامة <form> وفقًا للطريقة المحددة بواسطة سمة method لنفس العلامة.
value="إرسال": النص المعروض على الزر

2.8.1.11. زر من نوع reset

bouton de type reset
<input type="reset" value="إعادة الضبط" name="cmdRétablir">

Image

balise HTML
<input type="reset" value="إعادة الضبط" name="cmdRétablir">
attributs
type="reset": يحدد الزر على أنه زر إعادة تعيين النموذج. عندما ينقر العميل على هذا الزر، سيعيد المتصفح النموذج إلى الحالة التي استلمه بها.
value="إعادة الضبط" : النص المعروض على الزر

2.8.1.12. حقل مخفي

champ caché
<input type="hidden" name="secret" value="uneValeur">
balise HTML
<input type="hidden" name="..." value="...">
attributs
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. لنرى من خلال مثال الفرق بين الطريقتين. نستأنف المثال السابق ونعالجه بالطريقة التالية:

  1. يطلب متصفحًّا نموذج URL الوارد في المثال من خادم الويب
  2. بمجرد الحصول على النموذج، نقوم بتعبئته
  3. قبل إرسال قيم النموذج إلى خادم الويب بالنقر على الزر Envoyer من النوع submit، نقوم بإيقاف خادم الويب واستبداله بخادم TCP العام الذي سبق استخدامه سابقًا. تجدر الإشارة إلى أن هذا الخادم يعرض على الشاشة أسطر النص التي يرسلها إليه عميل الويب. وبذلك سنرى بالضبط ما يرسله المتصفح.

يتم ملء النموذج على النحو التالي:

Image

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

Image

2.8.2.1. طريقة GET

تم برمجة المستند HTML بحيث يستخدم المتصفح الطريقة GET لإرسال قيم النموذج إلى خادم الويب. لذلك كتبنا:

    <form method="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:

Image

إليك ما يتلقاه الخادم العام 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&param2=القيمة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>لا
- قيمة السمة 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=القائمة 3
- القيمة التي اختارها المستخدم من قائمة الاختيار الفردي
<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 للحقل المخفي

لنكرر نفس العملية، ولكن هذه المرة مع ترك الخادم الإلكتروني يقوم بإنشاء الرد، ولنرى ما هو هذا الرد. الصفحة التي أرسلها الخادم الإلكتروني هي التالية:

Image

وهي بالضبط نفس الصفحة التي تم استلامها في البداية قبل ملء النموذج. لفهم السبب، يجب إعادة النظر في 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، وهي صفحة ثابتة، هذه القيم. وبالتالي، فإن GET السابقة تعادل

<-- GET /html/balises.htm HTTP/1.1

ولهذا السبب أعاد الخادم إلينا الصفحة الأصلية مرة أخرى. وتجدر الإشارة إلى أن المتصفح يعرض بالفعل الرابط الكامل URL الذي تم طلبه:

Image

2.8.2.2. طريقة POST

تم برمجة المستند HTML بحيث يستخدم المتصفح الآن الطريقة POST لإرسال قيم النموذج إلى خادم الويب:

    <form method="POST" >

نقوم بإيقاف خادم الويب وتشغيل الخادم العام TCP (الذي سبق أن تناولناه ولكن تم تعديله قليلاً لهذه المناسبة) على المنفذ 81:

E:\data\serge\JAVA\SOCKETS\serveur générique>java serveurTCPgenerique2 81
Serveur générique lancé sur le port 81

الآن، نعود إلى متصفحنا لإرسال بيانات النموذج إلى خادم الويب باستخدام زر «إرسال»:

Image

إليكم ما يتلقاه الخادم العام 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

بالمقارنة مع ما نعرفه بالفعل، نلاحظ التغييرات التالية في استعلام المتصفح:

  1. لم يعد الرأس الأولي HTTP هو GET بل أصبح POST. صيغة الطلب هي POST URL HTTP/1.1، حيث يمثل URL قيمة URL التي طلبها المتصفح. وفي الوقت نفسه، يشير POST إلى أن المتصفح لديه بيانات ليرسلها إلى الخادم.
  2. تشير السطر Content-Type: application/x-www-form-urlencoded إلى نوع البيانات التي سيرسلها المتصفح. وهي بيانات نموذج (x-www-form) مشفرة (urlencoded). يؤدي هذا التشفير إلى تحويل بعض أحرف البيانات المرسلة لتجنب حدوث أخطاء في تفسيرها من قبل الخادم. وبالتالي، يتم استبدال المسافة بعلامة +، وعلامة نهاية السطر بعلامة %OD%OA،... بشكل عام، يتم تحويل جميع الأحرف الموجودة في البيانات والتي قد يؤدي تفسيرها إلى أخطاء من قبل الخادم (&، +، %، ...) إلى %XX حيث يمثل XX الرمز السداسي العشري لكل حرف.
  3. تشير السطر Content-Length: 210 إلى الخادم بعدد الأحرف التي سيرسلها العميل إليه بمجرد انتهاء الرؤوس HTTP، c.a.d، بعد السطر الفارغ الذي يشير إلى نهاية الرؤوس.
  4. البيانات (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&param2=val2&.... ويمكن النظر إلى ذلك على أنه ميزة أو عيب:

  • ميزة إذا أردنا السماح للمستخدم بإضافة رابط URL المُعدّ بهذه المعلمات إلى قائمة الروابط المفضلة لديه
  • وهي عيب إذا كنا لا نرغب في أن يتمكن المستخدم من الوصول إلى بعض المعلومات الواردة في النموذج، مثل الحقول المخفية على سبيل المثال

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

2.8.2.3. استرداد قيم نموذج ويب

لا يمكن بأي حال من الأحوال لصفحة ثابتة يُطلب عرضها من قبل عميل يرسل مع ذلك معلمات عبر POST أو GET أن تسترد هذه المعلمات. لا يمكن ذلك إلا لبرنامج، وهو الذي سيتولى عندئذٍ إنشاء استجابة للعميل، وهي استجابة ستكون ديناميكية وتعتمد عمومًا على المعلمات المستلمة. هذا هو مجال برمجة الويب، وهو مجال سنتناوله بمزيد من التفصيل في الفصل التالي مع عرض تقنيات Java لبرمجة الويب: السيرفلتات (servlets) وصفحات JSP.