Skip to content

2. Podstawy

W niniejszym rozdziale przedstawiamy podstawy programowania internetowego. Jego głównym celem jest zapoznanie czytelnika z głównymi zasadami programowania internetowego przed zastosowaniem ich w praktyce przy użyciu konkretnego języka i środowiska. Zawiera on liczne przykłady, które warto przetestować, aby stopniowo „wczuć się” w filozofię tworzenia aplikacji internetowych.

2.1. Elementy składowe aplikacji internetowej

Numer
Rola
Typowe przykłady
1
OS Serwer
Linux, Windows
2
Serwer WWW
Apache (Linux, Windows)
IIS (NT), PWS (Win9x)
3
Skrypty wykonywane po stronie serwera. Mogą być uruchamiane przez moduły
serwera lub przez programy zewnętrzne względem serwera (CGI).
PERL (Apache, IIS, PWS)
VBSCRIPT (IIS, PWS)
JAVASCRIPT (IIS, PWS)
PHP (Apache, IIS, PWS)
JAVA (Apache, IIS, PWS)
C#, VB.NET (IIS)
4
Baza danych – może znajdować się na tym samym komputerze
co program, który z niej korzysta, lub na innym komputerze za pośrednictwem Internetu.
Oracle (Linux, Windows)
MySQL (Linux, Windows)
Access (Windows)
SQL Server (Windows)
5
OS Klient
Linux, Windows
6
Przeglądarka internetowa
Netscape, Internet Explorer
7
Skrypty uruchamiane po stronie klienta w przeglądarce.
Skrypty te nie mają dostępu do dysków komputera klienckiego.
VBscript (IE)
JavaScript (IE, Netscape)
PerlScript (IE)
Aplety JAVA

2.2. Wymiana danych w aplikacji internetowej z formularzem

Numer
Rola
1
Przeglądarka po raz pierwszy żąda kodu URL dla kodu (http://machine/url). Nie przekazano żadnych parametrów.
2
Serwer WWW wysyła mu stronę internetową o tym URL. Może to być strona statyczna lub wygenerowana dynamicznie przez skrypt serwera (SA), który mógł wykorzystać zawartość baz danych (SB, SC). W tym przypadku skrypt wykryje, że żądano pliku URL bez przekazania parametrów, i wygeneruje początkową stronę WEB.
Przeglądarka odbiera stronę i wyświetla ją (CA). Skrypty po stronie przeglądarki (CB) mogły zmodyfikować stronę początkową wysłaną przez serwer. Następnie, w wyniku interakcji między użytkownikiem (CD) a skryptami (CB), strona internetowa zostanie zmodyfikowana. W szczególności zostaną wypełnione formularze.
3
Użytkownik zatwierdza dane z formularza, które następnie muszą zostać wysłane do serwera internetowego. Przeglądarka ponownie żąda pierwotnego skryptu URL lub innego, w zależności od sytuacji, i jednocześnie przekazuje serwerowi wartości z formularza. W tym celu może wykorzystać dwie metody o nazwach GET i POST. Po otrzymaniu żądania od klienta serwer uruchamia skrypt (SA) powiązany z żądanym URL, który wykrywa parametry i przetwarza je.
4
Serwer dostarcza stronę WEB wygenerowaną programowo (SA, SB, SC). Ten etap jest identyczny z poprzednim etapem 2. Wymiana danych odbywa się teraz zgodnie z etapami 2 i 3.

2.3. Kilka zasobów

Poniżej znajduje się lista zasobów umożliwiających instalację i korzystanie z niektórych narzędzi do tworzenia stron internetowych. W załączniku znajduje się instrukcja instalacji tych narzędzi.

Serveur Apache
- Apache, instalacja i wdrożenie, O'Reilly
Serveur IIS, PWS
PERL
- Programowanie w języku Perl, Larry Wall, O'Reilly
- Aplikacje w języku Perl: CGI, Neuss i Vromans, O'Reilly
- Dokumentacja HTML dołączona do pakietu Active Perl
PHP
- Programowanie stron internetowych z wykorzystaniem PHP, Lacroix, Eyrolles
- Podręcznik użytkownika PHP dostępny na stronie internetowej PHP
VBSCRIPT, ASP
- Interfejs między WEB a bazą danych w WinNT, Alex Homer, Eyrolles
JAVASCRIPT
HTML
JAVA
- JAVA Servlets, Jason Hunter, O'Reilly
- Programowanie sieciowe w języku Java, Elliotte Rusty Harold, O'Reilly
- JDBC i Java, George Reese, O'Reilly
Base de données
- Podręcznik dotyczący MySQL jest dostępny na stronie internetowej MySQL
- Oracle 8i pod systemem Linux, Gilles Briard, Eyrolles
- Oracle 8i pod NT, Gilles Briard, Eyrolles

2.4. Oznaczenia

W dalszej części będziemy zakładać, że zainstalowano pewną liczbę narzędzi i zastosujemy następujące oznaczenia:

oznaczenie
znaczenie
<apache>
katalog główny drzewa katalogów serwera Apache
<apache-DocumentRoot>
katalog główny stron internetowych dostarczanych przez serwer Apache. To właśnie w tym katalogu głównym muszą znajdować się strony internetowe. Tak więc adres http://localhost/page1.htm odpowiada plikowi <apache-DocumentRoot>\page1.htm.
<apache-cgi-bin>
katalog główny drzewa katalogów powiązanego z aliasem cgi-bin, w którym można umieścić skrypty CGI dla serwera Apache. W ten sposób URL http://localhost/cgi-bin/test1.pl odpowiada plikowi <apache-cgi-bin>\test1.pl.
<pws-DocumentRoot>
katalog główny stron internetowych generowanych przez PWS. Właśnie w tym katalogu głównym muszą znajdować się strony internetowe. Tak więc URL http://localhost/page1.htm odpowiada plikowi <pws-DocumentRoot>\page1.htm.
<perl>
katalog główny drzewa katalogów języka Perl. Plik wykonywalny perl.exe znajduje się zazwyczaj w katalogu <perl>\bin.
<php>
korzeń drzewa języka PHP. Plik wykonywalny php.exe znajduje się zazwyczaj w <php>.
<java>
katalogu głównego drzewa katalogów Java. Pliki wykonywalne powiązane z Javą znajdują się w <java>\bin.
<tomcat>
katalogu głównym serwera Tomcat. Przykłady serwletów znajdują się w katalogu <tomcat>\webapps\examples\servlets, a przykłady stron – w katalogu JSP w katalogu <tomcat>\webbapps\examples\jsp

W przypadku każdego z tych narzędzi należy zapoznać się z załącznikiem, który zawiera instrukcje dotyczące ich instalacji.

2.5. Strony internetowe statyczne, strony internetowe dynamiczne

Strona statyczna jest reprezentowana przez plik HTML. Strona dynamiczna jest natomiast generowana „na bieżąco” przez serwer WWW. W niniejszym akapicie proponujemy różne testy z wykorzystaniem różnych serwerów WWW i różnych języków programowania, aby pokazać uniwersalność koncepcji sieci WWW.

2.5.1. Strona statyczna HTML (język znaczników HyperText)

Rozważmy następujący kod HTML:


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

co generuje następującą stronę internetową:

Testy

Image

test1

  • uruchom serwer Apache
  • umieścić skrypt essai1.html w <apache-DocumentRoot>
  • wyświetlić stronę URL http://localhost/essai1.html w przeglądarce
  • zatrzymaj serwer Apache

test2

  • uruchom serwer PWS
  • umieścić skrypt essai1.html w pliku <pws-DocumentRoot>
  • wyświetlenie strony URL http://localhost/essai1.html w przeglądarce

2.5.2. Strona ASP (Active Server Pages)

Skrypt 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>

generuje następującą stronę internetową:

Image

Test

  • uruchom serwer PWS
  • umieść skrypt essai2.asp w <pws-DocumentRoot>
  • wywołaj adres http://localhost/essai2.asp za pomocą przeglądarki

2.5.3. Skrypt PERL (Practical Extracting and Reporting Language)

Skrypt 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
;

Pierwszy wiersz to ścieżka do pliku wykonywalnego perl.exe. W razie potrzeby należy ją dostosować. Po uruchomieniu przez serwer WWW skrypt generuje następującą stronę:

Image

Test

  • serwera WWW: Apache
  • dla informacji, należy przejrzeć plik konfiguracyjny srm.conf lub httpd.conf, w zależności od wersji Apache'a, znajdujący się w katalogu <apache>\confs i odszukaj wiersz dotyczący cgi-bin, aby poznać katalog <apache-cgi-bin>, w którym należy umieścić plik essai3.pl.
  • Umieść skrypt essai3.pl w katalogu <apache-cgi-bin>
  • wywołaj adres URL http://localhost/cgi-bin/essai3.pl

Należy zauważyć, że wyświetlenie strony perl zajmuje więcej czasu niż strony asp. Wynika to z faktu, że skrypt Perl jest wykonywany przez interpreter języka Perl, który musi zostać załadowany, zanim będzie mógł wykonać skrypt. Nie pozostaje on na stałe w pamięci.

2.5.4. Skrypt PHP (Personal Home Page, procesor HyperText)

Skrypt 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>

Powyższy skrypt generuje następującą stronę internetową:

Testy

Image

Image

  • przejrzyj plik konfiguracyjny srm.conf lub httpd.conf serwera Apache w <Apache>\confs

  • dla informacji sprawdź wiersze konfiguracyjne pliku php

test1

test2

  • uruchom serwer PWS

  • w celach informacyjnych sprawdzić konfigurację pliku PWS pod kątem PHP

  • umieścić essai4.php w <pws-DocumentRoot>\php

  • poprosić o URL http://localhost/essai4.php

2.5.5. Skrypt JSP (Java Server Pages)

Skrypt heure.jsp

<%  //program w Javie wyświetlający godzinę %>

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

<% 
     // kod JAVA do obliczania godziny
  Calendar calendrier=Calendar.getInstance();
  int heures=calendrier.get(Calendar.HOUR_OF_DAY);
  int minutes=calendrier.get(Calendar.MINUTE);
  int secondes=calendrier.get(Calendar.SECOND);
   // godziny, minuty i sekundy są zmiennymi globalnymi
   //, które będą mogły być wykorzystane w kodzie HTML
%>

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

Po uruchomieniu przez serwer WWW skrypt ten generuje następującą stronę:

Image

Testy

  • umieścić skrypt heure.jsp w katalogu <tomcat>\jakarta-tomcat\webapps\examples\jsp (Tomcat 3.x) lub w katalogu <tomcat>\webapps\examples\jsp (Tomcat 4.x)
  • uruchomić serwer Tomcat
  • wywołać stronę URL pod adresem http://localhost:8080/examples/jsp/heure.jsp

2.5.6. Wnioski

Powyższe przykłady pokazały, że:

  • strona HTML może być generowana dynamicznie przez program. Na tym właśnie polega programowanie internetowe.
  • że wykorzystywane języki i serwery internetowe mogą być zróżnicowane. Obecnie obserwuje się następujące główne trendy:
    • kombinacje Apache/PHP (Windows, Linux) oraz IIS/PHP (Windows)
    • technologia ASP.NET na platformach Windows, łącząca serwer IIS z językiem .NET (C#, VB.NET, ...)
    • technologia serwletów Java i stron JSP działająca z różnymi serwerami (Tomcat, Apache, IIS) oraz na różnych platformach (Windows, Linux). To właśnie ta ostatnia technologia zostanie szczegółowo omówiona w niniejszym dokumencie.

2.6. Skrypty po stronie przeglądarki

Strona HTML może zawierać skrypty, które będą wykonywane przez przeglądarkę. Istnieje wiele języków skryptowych po stronie przeglądarki. Oto kilka z nich:

Język
Obsługiwane przeglądarki
VBScript
IE
JavaScript
IE, Netscape
PerlScript
IE
Java
IE, Netscape

Weźmy kilka przykładów.

2.6.1. Strona internetowa ze skryptem VBScript po stronie przeglądarki

Strona 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>

Powyższa strona HTML zawiera nie tylko kod HTML, ale również program przeznaczony do wykonania przez przeglądarkę, która załaduje tę stronę. Kod wygląda następująco:

    <script language="vbscript">
      function reagir
        alert "Vous avez cliqué sur le bouton OK"
      end function
    </script>

Tagi <script></script> służą do wyodrębniania skryptów na stronie HTML. Skrypty te mogą być napisane w różnych językach, a to opcja language w tagu <script> określa używany język. W tym przypadku jest to VBScript. Nie będziemy się tutaj zagłębiać w szczegóły tego języka. Powyższy skrypt definiuje funkcję o nazwie réagir, która wyświetla komunikat. Kiedy ta funkcja jest wywoływana? Wskazuje nam to następujący wiersz kodu HTML:

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

Atrybut onclick określa nazwę funkcji, która ma zostać wywołana, gdy użytkownik kliknie przycisk OK. Gdy przeglądarka załaduje tę stronę, a użytkownik kliknie przycisk OK, pojawi się następująca strona:

Image

Testy

Tylko przeglądarka IE jest w stanie wykonywać skrypty VBScript. Przeglądarka Netscape wymaga do tego dodatkowych wtyczek. Można przeprowadzić następujące testy:

test1

  • serwer Apache
  • skrypt vbs1.html w <apache-DocumentRoot>
  • wywołanie adresu URL http://localhost/vbs1.html za pomocą przeglądarki IE

test2

  • serwer PWS
  • skrypt vbs1.html w <pws-DocumentRoot>
  • wywołaj adres URL http://localhost/vbs1.html za pomocą przeglądarki IE

2.6.2. Strona internetowa ze skryptem JavaScript po stronie przeglądarki

Strona: 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>

Mamy tu coś identycznego jak na poprzedniej stronie, z tą różnicą, że język VBScript zastąpiono językiem JavaScript. Ma on tę zaletę, że jest obsługiwany zarówno przez przeglądarkę IE, jak i Netscape. Jego wykonanie daje te same wyniki:

Image

Testy

test1

  • serwer Apache
  • skrypt js1.html w <apache-DocumentRoot>
  • wywołaj adres URL http://localhost/js1.html za pomocą przeglądarki IE lub Netscape

test2

  • serwer PWS
  • skrypt js1.html w <pws-DocumentRoot>
  • wywołaj adres URL http://localhost/js1.html za pomocą przeglądarki IE lub Netscape

2.7. Komunikacja między klientem a serwerem

Wróćmy do naszego początkowego schematu, który ilustrował elementy składowe aplikacji internetowej:

W tym miejscu skupiamy się na wymianie danych między komputerem klienckim a serwerem. Odbywa się ona za pośrednictwem sieci i warto przypomnieć ogólną strukturę wymiany danych między dwoma odległymi komputerami.

2.7.1. Model OSI

Model otwartej sieci o nazwie OSI (Open Systems Interconnection Reference Model), zdefiniowany przez ISO (Międzynarodową Organizację Normalizacyjną), opisuje idealną sieć, w której komunikację między komputerami można przedstawić za pomocą modelu siedmiowarstwowego:

Każda warstwa korzysta z usług warstwy niższej i udostępnia swoje usługi warstwie wyższej. Załóżmy, że dwie aplikacje znajdujące się na różnych maszynach A i B chcą się komunikować: robią to na poziomie warstwy Application. Nie muszą one znać wszystkich szczegółów działania sieci: każda aplikacja przekazuje informacje, które chce przesłać, do warstwy poniżej – warstwy Présentation. Aplikacja musi zatem znać jedynie zasady współpracy z warstwą Présentation. Gdy informacja znajdzie się w warstwie Présentation, jest przekazywana zgodnie z innymi regułami do warstwy Session i tak dalej, aż informacja dotrze do nośnika fizycznego i zostanie fizycznie przesłana do komputera docelowego. Tam zostanie poddana procesowi odwrotnemu do tego, który miała miejsce na komputerze nadawczym.

Na każdej warstwie proces nadawczy odpowiedzialny za wysyłanie informacji przekazuje ją do procesu odbiorczego na innym komputerze należącym do tej samej warstwy. Odbywa się to zgodnie z określonymi zasadami, zwanymi protokołem warstwy. Otrzymujemy zatem następujący ostateczny schemat komunikacji:

Rola poszczególnych warstw jest następująca:

Physique
Zapewnia transmisję bitów na nośniku fizycznym. W tej warstwie znajdują się urządzenia końcowe do przetwarzania danych (E.T.T.D.), takie jak terminal lub komputer, a także urządzenia końcowe obwodów danych (E.T.C.D.), takie jak modulator/demodulator, multiplekser, koncentrator. Istotne elementy na tym poziomie to:
. wybór sposobu kodowania informacji (analogowego lub cyfrowego)
. wybór trybu transmisji (synchroniczny lub asynchroniczny).
Liaison de données
Ukrywa specyfikę warstwy fizycznej. Wykrywa i koryguje błędy transmisji.
Réseau
Zarządza ścieżką, którą muszą podążać informacje wysyłane w sieci. Nazywa się to routage: określenie trasy, którą musi podążać informacja, aby dotarła do odbiorcy.
Transport
Umożliwia komunikację między dwiema aplikacjami, podczas gdy poprzednie warstwy pozwalały jedynie na komunikację między maszynami. Usługą świadczoną przez tę warstwę może być multipleksowanie: warstwa transportowa może wykorzystywać to samo połączenie sieciowe (między maszynami) do przesyłania informacji należących do kilku aplikacji.
Session
W tej warstwie znajdują się usługi umożliwiające aplikacji otwarcie i utrzymanie sesji roboczej na zdalnym komputerze.
Présentation
Ma ona na celu ujednolicenie sposobu przedstawiania danych na różnych komputerach. W ten sposób dane pochodzące z komputera A zostaną „przetworzone” przez warstwę Présentation komputera A zgodnie ze standardowym formatem, zanim zostaną wysłane do sieci. Po dotarciu do warstwy Présentation komputera docelowego B, który rozpozna je dzięki standardowemu formatowi, zostaną one przetworzone w inny sposób, aby aplikacja komputera B mogła je rozpoznać.
Application
Na tym poziomie znajdują się aplikacje zazwyczaj bliskie użytkownikowi, takie jak poczta elektroniczna czy przesyłanie plików.

2.7.2. Model TCP/IP

Model OSI jest modelem idealnym. Zestaw protokołów TCP/IP zbliża się do niego w następującej postaci:

  • interfejs sieciowy (karta sieciowa komputera) pełni funkcje warstw 1 i 2 modelu OSI
  • warstwa IP (Internet Protocol) pełni funkcje warstwy 3 (sieć)
  • warstwa TCP (Transfer Control Protocol) lub UDP (User Datagram Protocol) pełni funkcje warstwy 4 (transportowej). Protokół TCP zapewnia, że pakiety danych wymieniane między urządzeniami dotrą do miejsca przeznaczenia. Jeśli tak się nie stanie, odsyła zagubione pakiety. Protokół UDP nie wykonuje tej czynności, więc zadanie to spoczywa na programiście aplikacji. Dlatego w Internecie, który nie jest siecią w 100% niezawodną, najczęściej stosowany jest protokół TCP. Mówimy wówczas o sieci TCP-IP.
  • Warstwa aplikacji obejmuje funkcje poziomów od 5 do 7 modelu OSI.

Aplikacje internetowe znajdują się w warstwie Application i opierają się zatem na protokołach TCP-IP. Warstwy Application na komputerach klienckich i serwerze wymieniają między sobą komunikaty, które są przekazywane warstwom od 1 do 4 modelu w celu dostarczenia do miejsca przeznaczenia. Aby się porozumieć, warstwy aplikacji obu komputerów muszą „mówić” tym samym językiem lub protokołem. Protokół aplikacji internetowych nosi nazwę HTTP (HyperText Transfer Protocol). Jest to protokół tekstowy, c.a.d, dzięki któremu urządzenia wymieniają między sobą wiersze tekstu w sieci, aby się porozumieć. Wymiana ta jest znormalizowana, co oznacza, że klient dysponuje pewną liczbą komunikatów, aby dokładnie wskazać serwerowi, czego oczekuje, a serwer również dysponuje pewną liczbą komunikatów, aby udzielić klientowi odpowiedzi. Ta wymiana komunikatów ma następującą postać:

Klient --> Serwer

Gdy klient wysyła żądanie do serwera WWW, przesyła

  1. wiersze tekstu w formacie HTTP, aby wskazać, czego oczekuje
  1. pustą linię
  2. opcjonalnie dokument

Serwer --> Klient

Gdy serwer wysyła odpowiedź do klienta, przesyła

  1. wiersze tekstu w formacie HTTP, aby wskazać, co wysyła
  2. pusty wiersz
  3. opcjonalnie dokument

Wymiana danych ma zatem tę samą formę w obu kierunkach. W obu przypadkach może nastąpić wysłanie dokumentu, nawet jeśli rzadko zdarza się, by klient wysyłał dokument do serwera. Jednak protokół HTTP to przewiduje. To właśnie pozwala na przykład abonentom dostawcy usług internetowych na pobieranie różnych dokumentów na swoją stronę osobistą hostowaną u tego dostawcy. Wymieniane dokumenty mogą być dowolne. Weźmy na przykład przeglądarkę żądającą strony internetowej zawierającej obrazy:

  1. przeglądarka łączy się z serwerem internetowym i żąda żądanej strony. Żądane zasoby są jednoznacznie identyfikowane za pomocą URL (Uniform Resource Locator). Przeglądarka wysyła jedynie nagłówki HTTP, a nie sam dokument.
  2. Serwer odpowiada na to żądanie. Najpierw wysyła nagłówki HTTP, wskazujące, jaki typ odpowiedzi wysyła. Może to być komunikat o błędzie, jeśli żądana strona nie istnieje. Jeśli strona istnieje, serwer poinformuje w nagłówkach HTTP swojej odpowiedzi, że po nich wyśle dokument HTML (HyperText Markup Language). Dokument ten stanowi ciąg wierszy tekstu w formacie HTML. Tekst HTML zawiera znaczniki (tagi), które dostarczają przeglądarce wskazówek dotyczących sposobu wyświetlania tekstu.
  3. Klient na podstawie nagłówków HTTP wysłanych przez serwer wie, że otrzyma dokument HTML. Przeanalizuje go i być może zauważy, że zawiera odniesienia do obrazów. Obrazy te nie znajdują się w dokumencie HTML. W związku z tym wysyła nowe żądanie do tego samego serwera WWW, prosząc o pierwszy potrzebny mu obraz. Żądanie to jest identyczne z tym wysłanym w punkcie 1, z tą różnicą, że żądany zasób jest inny. Serwer przetworzy to żądanie, wysyłając klientowi żądany obraz. Tym razem w odpowiedzi nagłówki HTTP będą wskazywać, że wysłany plik to obraz, a nie dokument HTML.
  4. Klient pobiera przesłany obraz. Etapy 3 i 4 będą powtarzane, dopóki klient (zazwyczaj przeglądarka) nie otrzyma wszystkich dokumentów umożliwiających wyświetlenie całej strony.

2.7.3. Protokół HTTP

Przyjrzyjmy się protokołowi HTTP na przykładach. Jakie dane wymieniają między sobą przeglądarka i serwer WWW?

2.7.3.1. Odpowiedź serwera HTTP

Zobaczymy tutaj, w jaki sposób serwer internetowy odpowiada na żądania swoich klientów. Serwis internetowy lub serwis HTTP to serwis TCP-IP, który zazwyczaj działa na porcie 80. Może jednak działać na innym porcie. W takim przypadku przeglądarka klienta musiałaby podać ten port w żądaniu URL. Żądanie URL ma ogólną postać:

protocole://maszyna[:port]/ścieżka/informacje

z

protokołem
HTTP dla serwisu internetowego. Przeglądarka może również pełnić rolę klienta usług FTP, news, telnet itp.
nazwa
nazwa komputera, na którym działa usługa internetowa
port
port serwisu internetowego. Jeśli jest to 80, można pominąć numer portu. Jest to najczęstszy przypadek
ścieżka
ścieżka wskazująca żądany zasób
informacje
dodatkowe informacje przekazywane serwerowi w celu doprecyzowania żądania klienta

Co robi przeglądarka, gdy użytkownik żąda załadowania pliku URL?

  1. otwiera połączenie TCP-IP z maszyną i portem wskazanymi w części machine[:port] pliku URL. Nawiązanie połączenia TCP-IP oznacza utworzenie „kanału” komunikacyjnego między dwoma maszynami. Po utworzeniu tego kanału wszystkie informacje wymieniane między tymi maszynami będą przez niego przepływać. Utworzenie tego kanału TCP-IP nie wiąże się jeszcze z wykorzystaniem protokołu internetowego HTTP.
  2. Po utworzeniu kanału TCP-IP klient wyśle żądanie do serwera internetowego, wysyłając mu wiersze tekstu (polecenia) w formacie HTTP. Wyśle on do serwera część ścieżki/informacji z URL
  3. serwer odpowie w ten sam sposób i w tym samym kanale
  4. jeden z partnerów podejmie decyzję o zamknięciu kanału. Zależy to od używanego protokołu HTTP. W przypadku protokołu HTTP 1.0 serwer zamyka połączenie po każdej swojej odpowiedzi. Zmusza to klienta, który musi wysłać kilka żądań w celu uzyskania różnych dokumentów tworzących stronę internetową, do nawiązywania nowego połączenia przy każdym żądaniu, co wiąże się z pewnymi kosztami. W przypadku protokołu HTTP/1.1 klient może poinstruować serwer, aby utrzymywał połączenie otwarte do momentu, aż klient poleci jego zamknięcie. Dzięki temu może pobrać wszystkie dokumenty strony internetowej za pomocą jednego połączenia i samodzielnie zamknąć je po otrzymaniu ostatniego dokumentu. Serwer wykryje to zamknięcie i również zamknie połączenie.

Aby zapoznać się z wymianą danych między klientem a serwerem internetowym, wykorzystamy generyczny klient TCP. Jest to program, który może pełnić rolę klienta dowolnej usługi wykorzystującej protokół komunikacyjny oparty na wierszach tekstowych, tak jak ma to miejsce w przypadku protokołu HTTP. Wiersze tekstowe będą wpisywane przez użytkownika za pomocą klawiatury. Wymaga to od niego znajomości protokołu komunikacyjnego usługi, z którą próbuje się połączyć. Odpowiedź serwera jest następnie wyświetlana na ekranie. Program został napisany w języku Java i znajduje się w załączniku. Używamy go tutaj w oknie DOS w systemie Windows i uruchamiamy go w następujący sposób:

java clientTCPgenerique machine port

z

nazwa
nazwa komputera, na którym działa usługa, z którą chcemy się połączyć
port
port, na którym usługa jest udostępniana

Na podstawie tych dwóch informacji program nawiąże połączenie o nazwie TCP-IP z wskazaną maszyną i portem. Połączenie to posłuży do wymiany wierszy tekstu między klientem a serwerem internetowym. Wiersze po stronie klienta są wpisywane przez użytkownika za pomocą klawiatury i wysyłane do serwera. Wiersze tekstowe zwracane przez serwer w odpowiedzi są wyświetlane na ekranie. W ten sposób może nawiązać się bezpośredni dialog między użytkownikiem korzystającym z klawiatury a serwerem internetowym. Wypróbujmy to na już przedstawionych przykładach. Utworzyliśmy następującą statyczną stronę o nazwie HTML:


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

które wyświetlamy w przeglądarce:

Image

Widać, że żądany adres URL to: http://localhost:81/essais/essai1.html. Serwer usługi internetowej to zatem localhost (=serwer lokalny), a port to 81. Jeśli poprosimy o wyświetlenie tekstu HTML tej strony internetowej (Widok/Źródło), znajdziemy tekst HTML utworzony początkowo:

Image

Teraz użyjmy naszego ogólnego klienta TCP, aby zażądać tego samego 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>

Po uruchomieniu klienta za pomocą polecenia java clientTCPgenerique localhost 81 utworzono połączenie między programem a serwerem WWW działającym na tej samej maszynie (localhost) na porcie 81. Można rozpocząć wymianę danych między klientem a serwerem w formacie HTTP. Przypomnijmy, że składają się one z trzech elementów:

  1. nagłówki HTTP
  2. pusta linia
  3. dane opcjonalne

W naszym przykładzie klient wysyła tylko jedno żądanie:

GET /essais/essai1.html HTTP/1.0

Ten wiersz składa się z trzech elementów:

GET
polecenie HTTP służące do żądania zasobu. Istnieją również inne:
HEAD żąda zasobu, ale ogranicza się do nagłówków HTTP zawartych w odpowiedzi serwera. Sam zasób nie jest wysyłany.
PUT umożliwia klientowi wysłanie dokumentu do serwera
/essais/essai1.html
żądany zasób
HTTP/1.0
poziom używanego protokołu HTTP. W tym przypadku 1.0. Oznacza to, że serwer zamknie połączenie, gdy tylko wyśle swoją odpowiedź

Po nagłówkach HTTP zawsze musi następować pusty wiersz. Tak właśnie postąpił tutaj klient. W ten sposób klient lub serwer wie, że część HTTP wymiany została zakończona. W tym momencie dla klienta wszystko jest zakończone. Nie ma on żadnego dokumentu do wysłania. Następnie rozpoczyna się odpowiedź serwera, składająca się w naszym przykładzie ze wszystkich wierszy zaczynających się od znaku <--. Najpierw wysyła serwer serię nagłówków HTTP, po których następuje pusty wiersz:

<-- 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
serwer informuje,
  • że obsługuje protokół HTTP w wersji 1.1
  • że posiada żądany zasób (kod 200, komunikat OK)
Date: ...
data i godzina odpowiedzi
Server: 
serwer podaje swoje dane identyfikacyjne. W tym przypadku jest to serwer Apache
Last-Modified:
data ostatniej modyfikacji zasobu, o który poprosił klient
ETag:
...
Accept-Ranges: bytes
jednostka miary wysłanych danych. W tym przypadku bajt (byte)
Content-Length: 161
liczba bajtów dokumentu, który zostanie wysłany po nagłówkach HTTP. Liczba ta odpowiada w rzeczywistości rozmiarowi pliku w bajtach essai1.html:
E:\data\serge\web\essais>dir essai1.html

08/07/2002  10:00                  161 essai1.html
Connection: close
serwer informuje, że zamknie połączenie po wysłaniu dokumentu
Content-type: text/html
serwer informuje, że wyśle tekst (text) w formacie HTML (html).

Klient odbiera te nagłówki HTTP i wie już, że otrzyma 161 bajtów reprezentujących dokument HTML. Serwer wysyła te 161 bajtów bezpośrednio po pustej linii, która sygnalizowała koniec nagłówków HTTP:

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

Rozpoznajemy tu plik HTML utworzony na początku. Gdyby naszym klientem była przeglądarka, po odebraniu tych wierszy tekstu zinterpretowałaby je, aby wyświetlić użytkownikowi korzystającemu z klawiatury następującą stronę:

Image

Wykorzystajmy ponownie naszego generycznego klienta TCP, aby zażądać tego samego zasobu, ale tym razem za pomocą polecenia HEAD, które żąda wyłącznie nagłówków odpowiedzi:


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
<--

Otrzymujemy ten sam wynik co poprzednio, bez dokumentu HTML. Należy zauważyć, że w swoim żądaniu HEAD klient wskazał, że korzysta z protokołu HTTP w wersji 1.1. Wymusza to na nim wysłanie drugiego nagłówka HTTP, określającego parę machine:port, którą klient chce wywołać: Host: localhost:81.

Teraz spróbujmy pobrać obraz zarówno za pomocą przeglądarki, jak i za pomocą ogólnego klienta TCP. Najpierw za pomocą przeglądarki:

Image

Plik univ01.gif ma 3167 bajtów:

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

Teraz skorzystajmy z ogólnego klienta 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
<--

W odpowiedzi serwera należy zwrócić uwagę na następujące elementy:

HEAD
  • Żądamy jedynie nagłówków HTTP zasobu. Obraz jest bowiem plikiem binarnym, a nie tekstowym, a jego wyświetlenie na ekranie jako tekstu nie daje żadnego czytelnego wyniku.
Content-Length: 3167
  • to rozmiar pliku univ01.gif
Content-Type: image/gif
  • serwer informuje klienta, że wyśle mu dokument typu image/gif, c.a.d. obraz w formacie GIF. Gdyby obraz był w formacie JPEG, typ dokumentu wynosiłby image/jpeg. Typy dokumentów są ustandaryzowane i nazywane są typami MIME (Multi-purpose Mail Internet Extension).

2.7.3.2. Żądanie klienta HTTP

Zadajmy sobie teraz następujące pytanie: jeśli chcemy napisać program, który „komunikuje się” z serwerem WWW, jakie polecenia musi on wysłać do serwera WWW, aby uzyskać określony zasób? W poprzednich przykładach znaleźliśmy wstępną odpowiedź. Spotkaliśmy się z trzema poleceniami:

GET ressource protocole
  • w celu zażądania określonego zasobu zgodnie z określoną wersją protokołu HTTP. Serwer wysyła odpowiedź w formacie HTTP, po której następuje pusty wiersz, a następnie żądany zasób
HEAD ressource protocole
  • to samo, z tą różnicą, że w tym przypadku odpowiedź ogranicza się do nagłówków HTTP i pustego wiersza
host: machine:port
  • w celu określenia (protokół HTTP 1.1) komputera i portu serwera WWW, do którego skierowano zapytanie

Istnieją również inne polecenia. Aby je poznać, skorzystamy teraz z ogólnego serwera TCP. Jest to program napisany w języku Java, który również znajdziecie w załączniku. Uruchamia się go poleceniem: java serveurTCPgenerique portEcoute, gdzie portEcoute to port, z którym klienci muszą się połączyć. Program serveurTCPgenerique

  • wyświetla na ekranie polecenia wysłane przez klientów
  • i wysyła im w odpowiedzi wiersze tekstu wpisane przez użytkownika na klawiaturze. To właśnie ten program pełni rolę serwera. W naszym przykładzie użytkownik korzystający z klawiatury będzie pełnił rolę serwisu internetowego.

Zsymulujmy teraz serwer internetowy, uruchamiając nasz serwer ogólnego przeznaczenia na porcie 88:


Dos> java serveurTCPgenerique 88
Serveur générique lancé sur le port 88

Otwórzmy teraz przeglądarkę i wywołajmy adres http://localhost:88/exemple.html. Przeglądarka połączy się wówczas z portem 88 na serwerze localhost, a następnie zażąda strony /exemple.html:

Image

Przyjrzyjmy się teraz oknu naszego serwera, które wyświetla dane przesłane przez klienta (niektóre wiersze związane z działaniem programu serveurTCPgenerique zostały pominięte w celu uproszczenia):


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
<--

Wiersze poprzedzone znakiem <-- to te wysłane przez klienta. W ten sposób odkrywamy nagłówki HTTP, z którymi jeszcze się nie spotkaliśmy:

Accept:
  • lista typów dokumentów MIME, które przeglądarka potrafi przetworzyć.
Accept-language:
  • preferowany język dokumentów.
Accept-Encoding:
  • rodzaj kodowania dokumentów, które przeglądarka potrafi przetwarzać
User-Agent:
  • identyfikator klienta
Connection:
  • Close: serwer zamknie połączenie po wysłaniu odpowiedzi
  • Keep-Alive: połączenie pozostanie otwarte po otrzymaniu odpowiedzi z serwera. Umożliwi to przeglądarce żądanie pozostałych dokumentów niezbędnych do zbudowania strony bez konieczności ponownego nawiązywania połączenia.

Nagłówki HTTP wysyłane przez przeglądarkę kończą się pustym wierszem, zgodnie z oczekiwaniami.

Przygotujmy odpowiedź dla naszego klienta. Użytkownik korzystający z klawiatury jest tutaj prawdziwym serwerem i może ręcznie przygotować odpowiedź. Przypomnijmy sobie odpowiedź wysłaną przez serwer WWW w poprzednim przykładzie:

<-- 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>

Spróbujmy ręcznie (na klawiaturze) stworzyć podobną odpowiedź. Wiersze zaczynające się od --> : są wysyłane do klienta:

...
<-- 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

Polecenie fin jest związane z działaniem programu serveurTCPgenerique. Zatrzymuje ono wykonywanie programu i zamyka połączenie między serwerem a klientem. W naszej odpowiedzi ograniczyliśmy się do następujących nagłówków HTTP:

HTTP/1.1 200 OK
--> : Server: serveur tcp generique
--> : Connection: close
--> : Content-Type: text/html
--> :

Nie podajemy rozmiaru pliku, który zamierzamy wysłać (Content-Length), a jedynie informujemy, że po jego wysłaniu zamkniemy połączenie (Connection: close). To wystarczy dla przeglądarki. Gdy przeglądarka zauważy, że połączenie zostało zamknięte, uzna, że odpowiedź serwera została zakończona i wyświetli stronę HTML, która została jej przesłana. Wygląda ona następująco:

--> : <html>
--> :   <head><title>Serveur generique</title></head>
--> :   <body>
--> :     <center>
--> :       <h2>Reponse du serveur generique</h2>
--> :     </center>
--> :    </body>
--> : </html>

Przeglądarka wyświetla wówczas następującą stronę:

Image

Jeśli w powyższym przykładzie wpiszemy View/Source, aby sprawdzić, co otrzymała przeglądarka, otrzymamy:

Image

czyli dokładnie to, co wysłaliśmy z serwera generycznego.

2.8. Język HTML

Przeglądarka internetowa może wyświetlać różne dokumenty, z których najpopularniejszym jest dokument HTML (HyperText Markup Language). Jest to tekst sformatowany za pomocą znaczników o postaci <balise>texte</balise>. Na przykład tekst <B>important</B> wyświetli ważny fragment tekstu pogrubioną czcionką. Istnieją również pojedyncze znaczniki, takie jak znacznik <hr>, który wyświetla poziomą linię. Nie będziemy omawiać wszystkich znaczników, jakie można znaleźć w tekście HTML. Istnieje wiele programów WYSIWYG, które pozwalają na stworzenie strony internetowej bez pisania ani jednej linii kodu HTML. Narzędzia te automatycznie generują kod HTML na podstawie układu strony utworzonego za pomocą myszki i gotowych elementów sterujących. Można więc wstawić (za pomocą myszki) do strony tabelę, a następnie przejrzeć kod HTML wygenerowany przez oprogramowanie, aby dowiedzieć się, jakich tagów należy użyć do zdefiniowania tabeli na stronie internetowej. To naprawdę nie jest skomplikowane. Ponadto znajomość języka HTML jest niezbędna, ponieważ dynamiczne aplikacje internetowe muszą samodzielnie generować kod HTML, który ma być wysyłany do klientów internetowych. Kod ten jest generowany programowo i oczywiście trzeba wiedzieć, co należy wygenerować, aby klient otrzymał stronę internetową, której oczekuje.

Podsumowując, nie ma potrzeby znajomości całego języka HTML, aby rozpocząć programowanie internetowe. Jednak znajomość ta jest niezbędna i można ją zdobyć poprzez korzystanie z oprogramowania do tworzenia stron internetowych, takiego jak Word, FrontPage, DreamWeaver i dziesiątek innych. Innym sposobem na poznanie subtelności języka HTML jest przeglądanie sieci i wyświetlanie kodu źródłowego stron, które zawierają interesujące i jeszcze nieznane Ci funkcje.

2.8.1. Przykład

Rozważmy poniższy przykład, utworzony za pomocą FrontPage Express, bezpłatnego narzędzia dołączonego do przeglądarki Internet Explorer. Kod wygenerowany przez FrontPage został tutaj uproszczony. Przykład ten przedstawia kilka elementów, które można znaleźć w dokumencie internetowym, takich jak:

  • tabela
  • obraz
  • link

Image

Dokument HTML ma ogólną postać:

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

Cały dokument jest ujęty w tagi <html>...</html>. Składa się on z dwóch części:

  1. <head>...</head>: jest to niewidoczna część dokumentu. Zawiera informacje dla przeglądarki, która wyświetli dokument. Często znajduje się tam tag <title>...</title>, który określa tekst, jaki zostanie wyświetlony w pasku tytułu przeglądarki. Można tam również znaleźć inne tagi, w szczególności te definiujące słowa kluczowe dokumentu, wykorzystywane następnie przez wyszukiwarki. W tej części można również znaleźć skrypty, najczęściej napisane w języku JavaScript lub VBScript, które zostaną wykonane przez przeglądarkę.
  2. <body atrybuty>...</body>: jest to część, która zostanie wyświetlona przez przeglądarkę. Tagi zawarte w tej części wskazują przeglądarce „pożądany” wygląd dokumentu. Każda przeglądarka interpretuje te tagi na swój sposób. W związku z tym dwie przeglądarki mogą wyświetlać ten sam dokument internetowy w różny sposób. Jest to zazwyczaj jeden z problemów, z którymi borykają się projektanci stron internetowych.

Kod HTML naszego przykładowego dokumentu wygląda następująco:

<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>

W kodzie zaznaczono wyłącznie te elementy, które nas interesują:

Element
tagi i przykłady HTML
titre du document
<title>balises</title>
balises pojawi się w pasku tytułu przeglądarki wyświetlającej dokument
barre horizontale
<hr>: wyświetla poziomą kreskę
tableau
<atrybuty tabeli>....</table>: w celu zdefiniowania tabeli
<tr atrybuty>...</tr>: służy do zdefiniowania wiersza
<td atrybuty>...</td>: do zdefiniowania komórki
przykłady:
<table border="1">...</table>: atrybut border określa grubość obramowania tabeli
<td valign="middle" align="center" width="150">komórka(1,2)</td>: definiuje komórkę, której zawartością będzie komórka(1,2). Zawartość ta zostanie wyśrodkowana pionowo (valign="middle") i poziomo (align="center"). Komórka będzie miała szerokość 150 pikseli (width="150")
image
<img border="0" src="/images/univ01.gif" width="80" height="95">: definiuje obraz bez obramowania (border="0"), o wysokości 95 pikseli (height="95"), o szerokości 80 pikseli (width="80"), którego plik źródłowy znajduje się pod adresem /images/univ01.gif na serwerze internetowym (src="/images/univ01.gif"). Link ten znajduje się w dokumencie internetowym, który został wygenerowany za pomocą narzędzia URL http://localhost:81/html/balises.htm. W związku z tym przeglądarka zażąda pliku URL http://localhost:81/images/univ01.gif, aby pobrać obraz, do którego odwołuje się ten link.
lien
<a href="http://istia.univ-angers.fr">tutaj</a>: sprawia, że tekst ici służy jako link do strony URL http://istia.univ-angers.fr.
fond de page
<body background="/images/standard.jpg">: oznacza, że obraz, który ma służyć jako tło strony, znajduje się pod adresem URL /images/standard.jpg na serwerze internetowym. W kontekście naszego przykładu przeglądarka wyśle żądanie do adresu URL http://localhost:81/images/standard.jpg, aby pobrać ten obraz tła.

Na tym prostym przykładzie widać, że aby zbudować cały dokument, przeglądarka musi wysłać trzy żądania do serwera:

  1. http://localhost:81/html/balises.htm, aby pobrać kod źródłowy HTML dokumentu
  2. http://localhost:81/images/univ01.gif, aby pobrać obraz univ01.gif
  3. http://localhost:81/images/standard.jpg, aby uzyskać obraz tła o numerze standard.jpg

Poniższy przykład przedstawia formularz internetowy, który również został utworzony przy użyciu FrontPage.

Image

Kod HTML wygenerowany przez FrontPage i nieco uproszczony wygląda następująco:

<html>

  <head>
      <title>balises</title>
    <script language="JavaScript">
        function effacer(){
          alert("Vous avez cliqué sur le bouton Effacer");
      }//usuń
        </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>

Związek między kontrolą wizualną <--> znacznikiem HTML jest następujący:

Kontrola
tag HTML
formulaire
<form method="POST" >
champ de saisie
<input type="text" name="txtSaisie" size="20" value="kilka słów">
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">
wiersz1
wiersz 2
wiersz 3
</textarea>
boutons radio
<input type="radio" value="Tak" name="R1">Tak
<input type="radio" name="R1" value="nie" checked>Nie
cases à cocher
<input type="checkbox" name="C1" value="jeden">1
<input type="checkbox" name="C2" value="dwa" checked>2
<input type="checkbox" name="C3" value="trzy">3
Combo
<select size="1" name="cmbValeurs">
<option>opcja1</option>
<option selected>opcja 2</option>
<option>opcja 3</option>
</select>
liste à sélection unique
<select size="3" name="lst1">
<option selected>lista1</option>
<option>lista2</option>
<option>lista3</option>
<option>lista4</option>
<option>lista5</option>
</select>
liste à sélection multiple
<select size="3" name="lst2" multiple>
<option>lista1</option>
<option>lista2</option>
<option selected>lista3</option>
<option>lista4</option>
<option>lista5</option>
</select>
bouton de type submit
<input type="submit" value="Wyślij" name="cmdRenvoyer">
bouton de type reset
<input type="reset" value="Przywróć" name="cmdRétablir">
bouton de type button
<input type="button" value="Usuń" name="cmdEffacer" onclick="effacer()">

Przyjrzyjmy się tym różnym elementom sterującym.

2.8.1.1. Formularz

formulaire
<form method="POST" >
balise HTML
<form name="..." method="..." action="...">...</form>
attributs
name="frmexemple": nazwa formularza
method="..." : metoda używana przez przeglądarkę do wysyłania na serwer WWW wartości zebranych w formularzu
action="..." : adres, na który zostaną wysłane wartości zebrane w formularzu.
Formularz internetowy jest otoczony tagami <form>...</form>. Formularz może mieć nazwę (name="xx"). Dotyczy to wszystkich elementów kontrolnych, które można znaleźć w formularzu. Nazwa ta jest przydatna, jeśli dokument internetowy zawiera skrypty, które muszą odwoływać się do elementów formularza. Celem formularza jest zebranie informacji podanych przez użytkownika za pomocą klawiatury lub myszy oraz przesłanie ich do serwera internetowego o adresie URL. Którego? Tego, do którego odwołuje się atrybut action="URL". Jeśli ten atrybut nie występuje, informacje zostaną wysłane na serwer URL dokumentu, w którym znajduje się formularz. Tak byłoby w przypadku powyższego przykładu. Do tej pory zawsze postrzegaliśmy klienta internetowego jako „żądającego” informacji od serwera internetowego, a nigdy jako „przekazującego” mu informacje. W jaki sposób klient internetowy przekazuje informacje (zawarte w formularzu) do serwera internetowego? Omówimy to szczegółowo nieco później. Może on skorzystać z dwóch różnych metod o nazwach POST i GET. Atrybut method="méthode", z metodą równą GET lub POST, w tagu <form> wskazuje przeglądarce metodę, jaką należy zastosować do wysłania informacji zebranych w formularzu do adresu URL określonego przez atrybut action="URL". Gdy atrybut method nie jest określony, domyślnie stosowana jest metoda GET.

2.8.1.2. Pole wprowadzania danych

Image

Image

champ de saisie
<input type="text" name="txtSaisie" size="20" value="kilka słów">
<input type="password" name="txtMdp" size="20" value="unMotDePasse">
balise HTML
<input type="..." name="..." size=".." value="..">
Tag `input` służy do różnych elementów sterujących. To właśnie atrybut type pozwala odróżnić te różne elementy sterujące od siebie.
attributs
type="text": określa, że jest to pole wprowadzania danych
type="password": znaki w polu wprowadzania danych są zastępowane znakami *. To jedyna różnica w stosunku do zwykłego pola wprowadzania danych. Ten typ elementu kontrolnego nadaje się do wprowadzania haseł.
size="20": liczba znaków widocznych w polu – nie uniemożliwia wprowadzenia większej liczby znaków
name="txtSaisie": nazwa elementu sterującego
value="kilka słów": tekst, który będzie wyświetlany w polu wprowadzania danych.

2.8.1.3. Pole wprowadzania wielowierszowe

Image

champ de saisie multilignes
<textarea rows="2" name="areaSaisie" cols="20">
ligne1
ligne2
ligne3
</textarea>
balise HTML
<textarea ...>tekst</textarea>
wyświetla wielowierszowe pole wprowadzania tekstu, w którym początkowo znajduje się tekst
attributs
rows="2": liczba wierszy
cols="'20" : liczba kolumn
name="areaSaisie": nazwa kontrolki

2.8.1.4. Przyciski opcji

Image

boutons radio
<input type="radio" value="Tak" name="R1">Tak
<input type="radio" name="R1" value="nie" checked>Nie
balise HTML
<input type="radio" attribut2="valeur2" ....>tekst
wyświetla przycisk opcji z tekstem obok.
attributs
name="radio": nazwa elementu sterującego. Przyciski opcji o tej samej nazwie tworzą grupę przycisków, które wykluczają się wzajemnie: można zaznaczyć tylko jeden z nich.
value="wartość": wartość przypisana do przycisku opcji. Nie należy mylić tej wartości z tekstem wyświetlanym obok przycisku opcji. Ten ostatni służy wyłącznie do wyświetlania.
checked: jeśli to słowo kluczowe jest obecne, przycisk opcji jest zaznaczony, w przeciwnym razie nie jest.

2.8.1.5. Pola wyboru

cases à cocher
<input type="checkbox" name="C1" value="jeden">1
<input type="checkbox" name="C2" value="dwa" checked>2
<input type="checkbox" name="C3" value="trzy">3

Image

balise HTML
<input type="checkbox" attribut2="valeur2" ....>tekst
wyświetla pole wyboru z tekstem obok.
attributs
name="C1": nazwa elementu sterującego. Pola wyboru mogą, ale nie muszą mieć tę samą nazwę. Pola o tej samej nazwie tworzą grupę powiązanych pól.
value="wartość": wartość przypisana do pola wyboru. Nie należy mylić tej wartości z tekstem wyświetlanym obok przycisku opcji. Ten ostatni służy wyłącznie do wyświetlania.
checked: jeśli to słowo kluczowe występuje, przycisk opcji jest zaznaczony, w przeciwnym razie nie jest.

2.8.1.6. Lista rozwijana (combo)

Combo
<select size="1" name="cmbValeurs">
<option>choix1</option>
<option selected>opcja2</option>
<option>choix3</option>
</select>

Image

balise HTML
<select size=".." name="..">
<option [selected]>...</option>
...
</select>
wyświetla na liście teksty zawarte między tagami <option>...</option>
attributs
name="cmbValeurs": nazwa kontrolki.
size="1": liczba widocznych elementów listy. size="1" sprawia, że lista działa jak pole kombi.
selected: jeśli to słowo kluczowe występuje dla elementu listy, element ten pojawia się jako zaznaczony na liście. W naszym przykładzie powyżej element listy choix2 pojawia się jako zaznaczony element listy rozwijanej, gdy jest ona wyświetlana po raz pierwszy.

2.8.1.7. Lista z jednym elementem do wyboru

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

Image

balise HTML
<select size=".." name="..">
<option [selected]>...</option>
...
</select>
wyświetla na liście teksty zawarte między tagami <option>...</option>
attributs
takie same jak w przypadku listy rozwijanej wyświetlającej tylko jeden element. Ten element sterujący różni się od poprzedniej listy rozwijanej jedynie atrybutem size>1.

2.8.1.8. Lista z możliwością wielokrotnego wyboru

liste à sélection unique
<select size="3" name="lst2" multiple>
<option selected>lista1</option>
<option>liste2</option>
<option selected>lista3</option>
<option>liste4</option>
<option>liste5</option>
</select>

Image

balise HTML
<select size=".." name=".." multiple>
<option [selected]>...</option>
...
</select>
wyświetla na liście teksty zawarte między tagami <option>...</option>
attributs
multiple: umożliwia zaznaczenie wielu elementów z listy. W powyższym przykładzie zaznaczone są zarówno elementy liste1, jak i liste3.

2.8.1.9. Przycisk typu button

bouton de type button
<input type="button" value="Usuń" name="cmdEffacer" onclick="effacer()">

Image

balise HTML
<input type="button" value="..." name="..." onclick="effacer()" ....>
attributs
type="button": definiuje kontrolkę przycisku. Istnieją dwa inne typy przycisków: submit i reset.
value="Usuń": tekst wyświetlany na przycisku
onclick="funkcja()": pozwala zdefiniować funkcję, która ma zostać wykonana, gdy użytkownik kliknie przycisk. Funkcja ta jest częścią skryptów zdefiniowanych w wyświetlanym dokumencie internetowym. Powyższa składnia jest zgodna ze standardem javascript. Jeśli skrypty są napisane w języku VBScript, należy wpisać onclick="funkcja" bez nawiasów. Składnia pozostaje taka sama, jeśli do funkcji trzeba przekazać parametry: onclick="funkcja(val1, val2,...)"
W naszym przykładzie kliknięcie przycisku Effacer wywołuje następującą funkcję JavaScript effacer:
    <script language="JavaScript">
        function effacer(){
          alert("Vous avez cliqué sur le bouton Effacer");
      }//usuń
        </script>
Funkcja effacer wyświetla komunikat:

2.8.1.10. Przycisk typu „submit”

bouton de type submit
<input type="submit" value="Wyślij" name="cmdRenvoyer">

Image

balise HTML
<input type="submit" value="Wyślij" name="cmdRenvoyer">
attributs
type="submit": określa przycisk jako przycisk wysyłający dane formularza do serwera internetowego. Gdy użytkownik kliknie ten przycisk, przeglądarka wyśle dane formularza do adresu URL określonego w atrybucie action tagu <form> zgodnie z metodą określoną przez atrybut method tego samego tagu.
value="Wyślij": tekst wyświetlany na przycisku

2.8.1.11. Przycisk typu reset

bouton de type reset
<input type="reset" value="Przywróć" name="cmdRétablir">

Image

balise HTML
<input type="reset" value="Przywróć" name="cmdRétablir">
attributs
type="reset": określa przycisk jako przycisk resetowania formularza. Gdy użytkownik kliknie ten przycisk, przeglądarka przywróci formularz do stanu, w jakim go otrzymała.
value="Przywróć" : tekst wyświetlany na przycisku

2.8.1.12. Ukryte pole

champ caché
<input type="hidden" name="secret" value="uneValeur">
balise HTML
<input type="hidden" name="..." value="...">
attributs
type="hidden": określa, że jest to pole ukryte. Pole ukryte stanowi część formularza, ale nie jest widoczne dla użytkownika. Jeśli jednak użytkownik poprosiłby przeglądarkę o wyświetlenie kodu źródłowego, zobaczyłby tag <input type="hidden" value="..."> i tym samym wartość pola ukrytego.
value="uneValeur": wartość pola ukrytego.
Jaka jest rola pola ukrytego? Pozwala ono serwerowi internetowemu na zachowanie informacji w trakcie kolejnych żądań wysyłanych przez klienta. Rozważmy przykład aplikacji do zakupów internetowych. Klient kupuje pierwszy produkt o numerze art1 w ilości q1 na pierwszej stronie katalogu, a następnie przechodzi do kolejnej strony katalogu. Aby zapamiętać, że klient kupił q1 sztuk produktu art1, serwer może umieścić te dwie informacje w ukrytym polu formularza internetowego na nowej stronie. Na tej nowej stronie klient kupuje produkty o numerach q2 i art2. Gdy dane z tego drugiego formularza zostaną wysłane na serwer (submit), serwer otrzyma nie tylko informację (q2,art2), ale także (q1,art1), które również stanowią część formularza jako ukryte pola, których użytkownik nie może modyfikować. Serwer WWW umieści wówczas w nowym ukrytym polu informacje (q1,art1) oraz (q2,art2) i wyśle nową stronę katalogu. I tak dalej.

2.8.2. Wysyłanie wartości formularza do serwera WWW przez klienta WWW

W poprzednim rozdziale wspomnieliśmy, że klient internetowy dysponuje dwiema metodami wysyłania do serwera internetowego wartości z wyświetlonego formularza: metodami GET i POST. Przyjrzyjmy się na przykładzie różnicy między tymi dwiema metodami. Wróćmy do poprzedniego przykładu i potraktujmy go w następujący sposób:

  1. przeglądarka wysyła żądanie dotyczące formularza z przykładu o numerze URL do serwera internetowego
  2. po otrzymaniu formularza wypełniamy go
  3. zanim wyślemy wartości formularza do serwera internetowego, klikając przycisk o typie submit o nazwie Envoyer, zatrzymujemy serwer internetowy i zastępujemy go generycznym serwerem TCP, z którego korzystaliśmy już wcześniej. Przypomnijmy, że serwer ten wyświetla na ekranie wiersze tekstu przesłane przez klienta internetowego. W ten sposób zobaczymy, co dokładnie wysyła przeglądarka.

Formularz wypełnia się w następujący sposób:

Image

Kod URL użyty w tym dokumencie wygląda następująco:

Image

2.8.2.1. Metoda GET

Dokument HTML jest zaprogramowany tak, aby przeglądarka wykorzystywała metodę GET do wysyłania wartości formularza na serwer WWW. Wpisaliśmy zatem:

    <form method="GET" >

Wyłączamy serwer WWW i uruchamiamy nasz ogólny serwer TCP na porcie 81:

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

Teraz wracamy do przeglądarki, aby wysłać dane z formularza do serwera WWW za pomocą przycisku Envoyer:

Image

Oto, co otrzymuje serwer generyczny 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
<--

Wszystko znajduje się w pierwszym nagłówku HTTP wysłanym przez przeglądarkę:

<-- 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

Widać, że jest on znacznie bardziej złożony niż te, z którymi mieliśmy do czynienia do tej pory. Znajdujemy w nim składnię GET URL HTTP/1.1, ale w szczególnej postaci: GET URL?param1=wartość1&param2=wartość2&... HTTP/1.1, gdzie parami to nazwy elementów kontrolnych formularza internetowego, a wartości to przypisane do nich wartości. Przyjrzyjmy się im bliżej. Poniżej przedstawiamy tabelę z trzema kolumnami:

  • kolumna 1: zawiera definicję elementu sterującego HTML z przykładu
  • kolumna 2: przedstawia wygląd tego elementu w przeglądarce
  • kolumna 3: przedstawia wartość wysyłaną do serwera przez przeglądarkę dla elementu z kolumny 1 w postaci, jaką ma ona w zapytaniu GET z przykładu
element sterujący HTML
wygląd
zwracana(-e) wartość(-i)
<input type="radio" value="Tak" name="R1">Tak
<input type="radio" name="R1" value="nie" checked>Nie
– wartość atrybutu value przycisku opcji zaznaczonego przez użytkownika.
<input type="checkbox" name="C1" value="jeden">1
<input type="checkbox" name="C2" value="dwa" checked>2
<input type="checkbox" name="C3" value="trzy">3
C1=jeden
C2=dwa
– wartości atrybutów value pól zaznaczonych przez użytkownika
<input type="text" name="txtSaisie" size="20" value="kilka słów">
txtSaisie=programowanie+web
- tekst wpisany przez użytkownika w polu wprowadzania danych. Spacje zostały zastąpione znakiem +
<input type="password" name="txtMdp" size="20" value="unMotDePasse">
txtMdp=tojesttajemnica
- tekst wpisany przez użytkownika w polu wprowadzania danych
<textarea rows="2" name="areaSaisie" cols="20">
wiersz1
wiersz 2
wiersz 3
</textarea>
areaSaisie=podstawy+programowania+%0D%0A
programowania+stron+internetowych
– tekst wpisany przez użytkownika w polu wprowadzania danych. %OD%OA to znacznik końca linii. Spacje zostały zastąpione znakiem +
<select size="1" name="cmbValeurs">
<option>opcja1</option>
<option selected>opcja2</option>
<option>opcja3</option>
</select>
cmbValeurs=opcja3
– wartość wybrana przez użytkownika z listy z jednym wyborem
<select size="3" name="lst1">
<option selected>lista1</option>
<option>lista2</option>
<option>lista3</option>
<option>lista4</option>
<option>lista5</option>
</select>
lst1=lista3
- wartość wybrana przez użytkownika z listy z jednym wyborem
<select size="3" name="lst2" multiple>
<option selected>lista1</option>
<option>lista2</option>
<option selected>lista3</option>
<option>lista4</option>
<option>lista5</option>
</select>
lst2=lista1
lst2=lista3
- wartości wybrane przez użytkownika z listy wielokrotnego wyboru
<input type="submit" value="Wyślij" name="cmdRenvoyer">
 
cmdRenvoyer=Wyślij
- nazwa i atrybut value przycisku, który posłużył do wysłania danych formularza na serwer
<input type="hidden" name="secret" value="uneValeur">
 
secret=jakaswartość
- atrybut value pola ukrytego

Powtórzmy tę samą czynność, ale tym razem pozostawiając serwerowi WWW zadanie wygenerowania odpowiedzi i zobaczmy, jaka ona będzie. Strona zwrócona przez serwer WWW wygląda następująco:

Image

Jest to dokładnie ta sama strona, którą otrzymaliśmy początkowo, przed wypełnieniem formularza. Aby zrozumieć dlaczego, należy ponownie przyjrzeć się kodu URL, o który prosi przeglądarka, gdy użytkownik naciska przycisk 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

Żądana strona to /html/balises.htm. Ponadto do tej strony przekazywane są wartości z formularza. Na razie strona URL /html/balises.htm, która jest stroną statyczną, nie wykorzystuje tych wartości. W związku z tym poprzedni kod GET jest równoważny z

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

i właśnie dlatego serwer ponownie zwrócił nam stronę początkową. Należy zauważyć, że przeglądarka wyświetla prawidłowo pełną stronę URL, o którą prosiliśmy:

Image

2.8.2.2. Metoda POST

Dokument HTML jest zaprogramowany tak, aby przeglądarka korzystała teraz z metody POST w celu wysłania wartości formularza do serwera WWW:

    <form method="POST" >

Wyłączamy serwer WWW i uruchamiamy ogólny serwer TCP (już znany, ale nieco zmodyfikowany na tę okazję) na porcie 81:

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

Teraz wracamy do przeglądarki, aby wysłać dane z formularza do serwera WWW za pomocą przycisku „Wyślij”:

Image

Oto, co otrzymuje serwer generyczny 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

W porównaniu z tym, co już znamy, zauważamy następujące zmiany w zapytaniu przeglądarki:

  1. Pierwotny nagłówek HTTP nie brzmi już GET, lecz POST. Składnia to POST URL HTTP/1.1, gdzie URL to wartość żądana przez przeglądarkę. Jednocześnie POST oznacza, że przeglądarka ma dane do przesłania na serwer.
  2. Wiersz Content-Type: application/x-www-form-urlencoded wskazuje, jaki typ danych wyśle przeglądarka. Są to dane formularza (x-www-form) zakodowane (urlencoded). Kodowanie to powoduje, że niektóre znaki przesyłanych danych są przekształcane, aby uniknąć błędów interpretacji po stronie serwera. W ten sposób spacja jest zastępowana znakiem +, a znak końca linii – %OD%OA,... Ogólnie rzecz biorąc, wszystkie znaki zawarte w danych, które mogą zostać błędnie zinterpretowane przez serwer (&, +, %, ...), są przekształcane na %XX, gdzie XX to ich kod szesnastkowy.
  3. Wiersz Content-Length: 210 informuje serwer, ile znaków klient wyśle mu po zakończeniu nagłówków HTTP, c.a.d, po pustym wierszu sygnalizującym koniec nagłówków.
  4. Dane (210 znaków): R1=Tak&C1=jeden&C2=dwa&txtSaisie=programowanie+stron+internetowych&txtMdp=tojesttajemnica&areaSaisie=podstawy+programowania+webowego%0D%0Aprogramowanie+webowe&cmbValeurs=wybór3&lst1=lista3&lst2=lista1&lst2=lista3&cmdRenvoyer=Wyślij&secret=uneValeur

Zauważamy, że dane przesyłane przez POST mają ten sam format, co dane przesyłane przez GET.

Czy jedna z tych metod jest lepsza od drugiej? Widzieliśmy, że jeśli wartości z formularza były wysyłane przez przeglądarkę metodą GET, przeglądarka wyświetlała w polu Adresse żądany parametr URL w postaci URL?param1=val1&param2=val2&.... Można to postrzegać jako zaletę lub wadę:

  • zaletą, jeśli chcemy umożliwić użytkownikowi dodanie tego skonfigurowanego adresu URL do ulubionych
  • wadą, jeśli nie chcemy, aby użytkownik miał dostęp do niektórych informacji zawartych w formularzu, takich jak na przykład pola ukryte

W dalszej części będziemy stosować w naszych formularzach niemal wyłącznie metodę POST.

2.8.2.3. Pobieranie wartości z formularza internetowego

Strona statyczna wywołana przez klienta, który dodatkowo przesyła parametry za pomocą POST lub GET, nie jest w żaden sposób w stanie ich pobrać. Tylko program może to zrobić i to on zajmie się następnie wygenerowaniem odpowiedzi dla klienta – odpowiedzi, która będzie dynamiczna i zazwyczaj zależna od otrzymanych parametrów. Jest to dziedzina programowania internetowego, którą omówimy bardziej szczegółowo w następnym rozdziale wraz z prezentacją technologii programowania internetowego w Javie: serwletów i stron JSP.