Skip to content

2. De basis

In dit hoofdstuk behandelen we de basisbeginselen van het webprogrammeren. Het belangrijkste doel is om de belangrijkste principes van het webprogrammeren te laten ontdekken, die losstaan van de specifieke technologie die wordt gebruikt om ze toe te passen. Het bevat talrijke voorbeelden die u best zelf uitprobeert om u geleidelijk aan de filosofie van webontwikkeling eigen te maken. De gratis tools die nodig zijn om deze voorbeelden te testen, worden aan het einde van het document gepresenteerd in de bijlage getiteld „Webtools”.

2.1. De onderdelen van een webapplicatie

Machine Serveur

Image

15Client

Nummer
Rol
Veelvoorkomende voorbeelden
1
OS Server
Linux, Windows
2
Webserver
Apache (Linux, Windows)
IIS (NT), PWS (Win9x), Cassini (Windows + .NET-platform)
3
Scripts die aan de serverzijde worden uitgevoerd. Ze kunnen worden uitgevoerd door servermodules of door programma’s buiten de server (CGI).
PERL (Apache, IIS, PWS)
VBSCRIPT (IIS, PWS)
JAVASCRIPT (IIS, PWS)
PHP (Apache, IIS, PWS)
JAVA (Apache, IIS, PWS)
C#, VB.NET (IIS)
4
Database - Deze kan zich op dezelfde machine bevinden als het programma dat er gebruik van maakt, of op een andere machine via internet.
Oracle (Linux, Windows)
MySQL (Linux, Windows)
Postgres (Linux, Windows)
Access (Windows)
SQL Server (Windows)
5
OS Client
Linux, Windows
6
Webbrowser
Netscape, Internet Explorer, Mozilla, Opera
7
Scripts die aan de clientzijde in de browser worden uitgevoerd. Deze scripts hebben geen toegang tot de schijven van de clientcomputer.
VBscript (IE)
JavaScript (IE, Netscape)
PerlScript (IE)
Applets JAVA

2.2. Gegevensuitwisseling in een webapplicatie met een formulier

Image

ClientcomputerServercomputer

Nummer
Rol
1
De browser vraagt voor de eerste keer om een URL (http://machine/url). Er worden geen parameters doorgegeven.
2
De webserver stuurt de webpagina van deze URL naar de browser. Deze kan statisch zijn of dynamisch gegenereerd worden door een serverscript (SA) dat mogelijk gebruik heeft gemaakt van de inhoud van databases (SB, SC). In dit geval zal het script detecteren dat URL is opgevraagd zonder dat er parameters zijn doorgegeven, en zal het de oorspronkelijke pagina WEB genereren.
De browser ontvangt de pagina en geeft deze weer (CA). Scripts aan de kant van de browser (CB) hebben de door de server verzonden oorspronkelijke pagina mogelijk gewijzigd. Vervolgens wordt de webpagina gewijzigd door interacties tussen de gebruiker (CD) en de scripts (CB). Met name worden de formulieren ingevuld.
3
De gebruiker bevestigt de gegevens in het formulier, die vervolgens naar de webserver moeten worden verzonden. De browser vraagt de oorspronkelijke URL of, afhankelijk van de situatie, een andere opnieuw op en stuurt tegelijkertijd de waarden van het formulier naar de server. Hiervoor kan hij gebruikmaken van twee methoden, namelijk GET en POST. Bij ontvangst van het verzoek van de client activeert de server het script (SA) dat gekoppeld is aan de aangevraagde URL; dit script detecteert de parameters en verwerkt deze.
4
De server levert de pagina WEB af die door het programma is opgebouwd (SA, SB, SC). Deze stap is identiek aan de vorige stap 2. De uitwisselingen verlopen nu volgens stap 2 en 3.

2.3. Notations

Hierna gaan we ervan uit dat een aantal tools is geïnstalleerd en hanteren we de volgende notaties:

notatie
betekenis
<apache>
hoofdmap van de Apache-boomstructuur
<apache-DocumentRoot>
root van de door Apache geleverde webpagina's. De webpagina's moeten zich onder deze root bevinden. Zo komt de URL URL http://localhost/page1.htm overeen met het bestand <apache-DocumentRoot>\page1.htm.
<apache-cgi-bin>
de hoofdmap van de boomstructuur die gekoppeld is aan de alias cgi-bin en waar CGI-scripts voor Apache kunnen worden geplaatst. Zo komt de URL http://localhost/cgi-bin/test1.pl overeen met het bestand <apache-cgi-bin>\test1.pl.
<IIS-DocumentRoot>
hoofdmap van de webpagina’s die worden geleverd door IIS, PWS of Cassini. De webpagina’s moeten zich onder deze root bevinden. Zo komt de URL URL http://localhost/page1.htm overeen met het bestand <IIS-DocumentRoot>\page1.htm.
<perl>
de hoofdmap van de Perl-boomstructuur. Het uitvoerbare bestand perl.exe bevindt zich doorgaans in <perl>\bin.
<php>
de root van de PHP-taalstructuur. Het uitvoerbare bestand php.exe bevindt zich doorgaans in <php>.
<java>
de hoofdmap van de Java-structuur. De uitvoerbare bestanden die verband houden met Java bevinden zich in <java>\bin.
<tomcat>
de hoofdmap van de Tomcat-server. Voorbeelden van servlets zijn te vinden in <tomcat>\webapps\examples\servlets en voorbeelden van pagina's in JSP en <tomcat>\webbapps\examples\jsp

Raadpleeg voor elk van deze tools de bijlage, waarin hulp wordt geboden bij de installatie ervan.

2.4. Statische webpagina’s, dynamische webpagina’s

Een statische pagina wordt weergegeven door een bestand HTML. Een dynamische pagina wordt daarentegen „on-the-fly“ door de webserver gegenereerd. In deze paragraaf stellen we diverse tests voor met verschillende webservers en programmeertalen om de universaliteit van het webconcept aan te tonen. We zullen twee webservers gebruiken, namelijk Apache en IIS. Hoewel IIS een commercieel product is, is er ook een gratis versie beschikbaar met beperktere functionaliteit:

  • PWS voor Win9x-computers
  • Cassini voor Windows 2000-computers en XP

De map <IIS-DocumentRoot> is doorgaans de map [lecteur:\inetpub\wwwroot], waarbij [lecteur] de schijf is (C, D, ...) waarop IIS is geïnstalleerd. Hetzelfde geldt voor PWS. Voor Cassini hangt de map <IIS-DocumentRoot> af van de manier waarop de server is gestart. In de bijlage wordt getoond dat de Cassini-server als volgt in een DOS-venster (of via een snelkoppeling) kan worden gestart:

dos>webserver /port:N /path:"P" /vpath:"/V"

De applicatie [WebServer], ook wel de Cassini-webserver genoemd, ondersteunt drie parameters:

  • /port: poortnummer van de webservice. Dit kan willekeurig zijn. Standaard is de waarde 80
  • /path: het fysieke pad naar een map op de schijf
  • /vpath: virtuele map die aan de voorgaande fysieke map is gekoppeld. Let erop dat de syntaxis niet /path=pad is, maar /vpath:pad, in tegenstelling tot wat in het bovenstaande helpvenster staat.

Als Cassini als volgt wordt gestart:

dos>webserver /port:N /path:"P" /vpath:"/"

dan is de map P de root van de webstructuur van de Cassini-server. Deze map wordt dus aangeduid met <IIS-DocumentRoot>. Zoals in het volgende voorbeeld:

dos12>webserver /path:"d:\data\devel\webmatrix" /vpath:"/"

werkt de Cassini-server op poort 80 en is de root van de webboomstructuur <IIS-DocumentRoot> de map [d:\data\devel\webmatrix]. De te testen webpagina’s moeten zich onder deze root bevinden.

Vervolgens wordt elke webapplicatie vertegenwoordigd door één enkel bestand dat met elk willekeurig tekstbestand kan worden aangemaakt. Er is geen IDE vereist.

2.4.1. Statische pagina HTML (HyperText Markup Language)

Laten we de volgende HTML-code eens bekijken:

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

wat de volgende webpagina oplevert:

De tests

Image

Test1

  • start de Apache-server
  • plaats het script essai1.html in <apache-DocumentRoot>
  • bekijk de pagina URL http://localhost/essai1.html met een browser
  • de Apache-server stoppen

Test2

  • de IIS/PWS/Cassini-server starten
  • het script essai1.html in <IIS-DocumentRoot> plaatsen
  • de pagina URL http://localhost/essai1.html bekijken met een browser

2.4.2. Een ASP-pagina (Active Server Pages)

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

levert de volgende webpagina op:

Image

De test

  • start de server IIS/PWS
  • plaats het script essai2.asp in <IIS-DocumentRoot>
  • roep de pagina URL http://localhost/essai2.asp op met een browser

2.4.3. Een script PERL (Practical Extracting and Reporting Language)

Het script 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
;

De eerste regel is het pad naar het uitvoerbare bestand perl.exe. Pas dit indien nodig aan. Zodra het script door een webserver wordt uitgevoerd, genereert het de volgende pagina:

Image

De test

  • webserver: Apache
  • Bekijk ter informatie het configuratiebestand srm.conf of httpd.conf, afhankelijk van de Apache-versie, in <apache>\confs en zoek de regel over cgi-bin om de map <apache-cgi-bin> te vinden waarin u essai3.pl moet plaatsen.
  • Plaats het script essai3.pl in <apache-cgi-bin>
  • roep de URL http://localhost/cgi-bin/essai3.pl op

Merk op dat het langer duurt om de pagina perl te laden dan de pagina asp. Dit komt doordat het Perl-script wordt uitgevoerd door een Perl-interpreter die eerst moet worden geladen voordat het script kan worden uitgevoerd. Deze blijft niet permanent in het geheugen staan.

2.4.4. Een script PHP (HyperText-processor)

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

Het bovenstaande script genereert de volgende webpagina:

Image

De tests

Test1

  • Raadpleeg het Apache-configuratiebestand srm.conf of httpd.conf in <Apache>\confs
  • ter informatie: controleer de configuratieregels van php
  • start de Apache-server
  • plaats essai4.php in <apache-DocumentRoot>
  • vraag de URL-http://localhost/essai4.php op

Test2

  • de server IIS/PWS starten
  • ter informatie: controleer de configuratie van PWS met betrekking tot PHP
  • essai4.php in <IIS-DocumentRoot>\php plaatsen
  • de URL opvragen http://localhost/essai4.php

2.4.5. Een script JSP (Java Server Pages)

Het script heure.jsp

<%  //Java-programma dat de tijd weergeeft %>

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

<% 
     // code JAVA om de tijd te berekenen
  Calendar calendrier=Calendar.getInstance();
  int heures=calendrier.get(Calendar.HOUR_OF_DAY);
  int minutes=calendrier.get(Calendar.MINUTE);
  int secondes=calendrier.get(Calendar.SECOND);
   // uren, minuten en seconden zijn globale variabelen
   // die in de code HTML kunnen worden gebruikt
%>

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

Zodra dit script door de webserver wordt uitgevoerd, genereert het de volgende pagina:

Image

De tests

  • plaats het script heure.jsp in <tomcat>\jakarta-tomcat\webapps\examples\jsp (Tomcat 3.x) of in <tomcat>\webapps\examples\jsp (Tomcat 4.x)
  • Start de Tomcat-server
  • de pagina URL opvragen via http://localhost:8080/examples/jsp/heure.jsp

2.4.6. Een pagina ASP.NET

Het script heure1.aspx:

<html>
<head>
    <title>Démo asp.net </title>
</head>
<body>
    Il est <% =Date.Now.ToString("hh:mm:ss") %>
</body>
</html>

Zodra dit script door de webserver wordt uitgevoerd, genereert het de volgende pagina:

Image

Voor deze test is een Windows-computer nodig waarop het platform .NET is geïnstalleerd (zie bijlage).

  • plaats het script heure1.aspx in <IIS-DocumentRoot>
  • start de server IIS/CASSINI
  • de URL opvragen via http://localhost/heure1.aspx

2.4.7. Conclusie

Uit de voorgaande voorbeelden is gebleken dat:

  • een pagina HTML dynamisch door een programma kan worden gegenereerd. Dat is de essentie van webprogrammering.
  • dat er verschillende programmeertalen en webservers kunnen worden gebruikt. Momenteel zien we de volgende grote trends:
    • de combinaties Apache/PHP (Windows, Linux) en IIS/PHP (Windows)
    • de ASP.NET-technologie op Windows-platforms, waarbij de IIS-server wordt gecombineerd met een .NET-taal (C#, VB.NET, ...)
    • de technologie van Java-servlets en JSP-pagina’s die werken met verschillende servers (Tomcat, Apache, IIS) en op verschillende platforms (Windows, Linux).

2.5. Scripts aan de browserzijde

Een HTML-pagina kan scripts bevatten die door de browser worden uitgevoerd. Er zijn talrijke scripttalen voor de browser. Hier volgen er enkele:

Taal
Ondersteunde browsers
VBScript
IE
JavaScript
IE, Netscape
PerlScript
IE
Java
IE, Netscape

Laten we een paar voorbeelden bekijken.

2.5.1. Een webpagina met een VBScript-script, aan de browserzijde

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

De bovenstaande pagina HTML bevat niet alleen de code HTML, maar ook een programma dat bedoeld is om te worden uitgevoerd door de browser die deze pagina heeft geladen. De code is als volgt:

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

De tags <script></script> worden gebruikt om de scripts op de pagina HTML af te bakenen. Deze scripts kunnen in verschillende talen worden geschreven en de optie language van de tag <script> geeft aan welke taal wordt gebruikt. In dit geval is dat VBScript. We zullen niet in detail ingaan op deze taal. Het bovenstaande script definieert een functie met de naam réagir die een bericht weergeeft. Wanneer wordt deze functie aangeroepen? Dat wordt aangegeven door de volgende coderegel HTML:

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

Het attribuut onclick geeft de naam aan van de functie die moet worden aangeroepen wanneer de gebruiker op de knop OK klikt. Zodra de browser deze pagina heeft geladen en de gebruiker op de knop OK klikt, verschijnt de volgende pagina:

Image

De tests

Alleen de browser IE kan VBScript-scripts uitvoeren. Netscape heeft hiervoor plug-ins nodig. De volgende tests kunnen worden uitgevoerd:

  • Apache-server
  • script vbs1.html in <apache-DocumentRoot>
  • de URL http://localhost/vbs1.html opvragen met de browser IE

  • server IIS/PWS

  • script vbs1.html in <pws-DocumentRoot>
  • de URL http://localhost/vbs1.html opvragen met de browser IE

Een webpagina met een JavaScript-script, aan de browserzijde

La page : js1.html

<html>
  <head>
    <title>essai 4 : une page web avec un script Javascript</title>
    <script language="javascript">
      function reagir(){
        alert ("Vous avez cliqué sur le bouton OK");
      }
    </script>
   </head>

   <body>
     <center>
     <h1>Une page Web avec un script Javascript</h1>
     <table>
       <tr>
         <td>Cliquez sur le bouton</td>
         <td><input type="button" value="OK" name="cmdOK" onclick="reagir()"></td>
       </tr>
    </table>
   </body>
</html>

Dit is in wezen hetzelfde als op de vorige pagina, behalve dat de taal VBScript is vervangen door JavaScript. Dit heeft als voordeel dat het door beide browsers, IE en Netscape, wordt ondersteund. De uitvoering levert dezelfde resultaten op:

Image

De tests

  • Apache-server
  • script js1.html in <apache-DocumentRoot>
  • de URL http://localhost/js1.html opvragen met de browser IE of Netscape

  • server IIS/PWS

  • script js1.html in <pws-DocumentRoot>
  • de URL http://localhost/js1.html opvragen met de browser IE of Netscape

2.6. De communicatie tussen client en server

Laten we terugkeren naar ons oorspronkelijke schema dat de actoren van een webapplicatie illustreerde:

Image

Server

We richten ons hier op de communicatie tussen de clientcomputer en de servercomputer. Deze communicatie vindt plaats via een netwerk en het is goed om de algemene structuur van de communicatie tussen twee computers op afstand nog eens in herinnering te brengen.

2.6.1. Het OSI-model

Het open netwerkmodel, OSI (Open Systems Interconnection Reference Model) genaamd, gedefinieerd door de ISO (International Standards Organisation), beschrijft een ideaal netwerk waarin de communicatie tussen computers kan worden weergegeven door een model met zeven lagen:

Image

Elke laag ontvangt diensten van de onderliggende laag en biedt haar eigen diensten aan de bovenliggende laag aan. Stel dat twee applicaties op verschillende machines A en B met elkaar willen communiceren: dat doen ze op het niveau van de Application-laag. Ze hoeven niet alle details van de werking van het netwerk te kennen: elke toepassing geeft de informatie die ze wil verzenden door aan de onderliggende laag: de laag Présentation. De toepassing hoeft dus alleen de regels voor de koppeling met de laag Présentation te kennen. Zodra de informatie zich in de laag Présentation bevindt, wordt deze volgens andere regels doorgegeven aan de laag Session en zo verder, totdat de informatie op het fysieke medium terechtkomt en fysiek naar de bestemmingsmachine wordt verzonden. Daar ondergaat de informatie het omgekeerde proces van wat er op de verzendende machine is gebeurd.

Op elke laag stuurt het verzendproces, dat verantwoordelijk is voor het verzenden van de informatie, deze naar een ontvangstproces op de andere machine die tot dezelfde laag behoort. Dit gebeurt volgens bepaalde regels die het protocol van de laag worden genoemd. We krijgen dus het volgende uiteindelijke communicatieschema:

Image

De rol van de verschillende lagen is als volgt:

Physique
Zorgt voor de overdracht van bits via een fysiek medium. In deze laag bevinden zich eindapparatuur voor gegevensverwerking (E.T.T.D), zoals terminals of computers, evenals apparatuur voor het afsluiten van datacircuits (E.T.C.D), zoals modulators/demodulators, multiplexers en concentrators. De aandachtspunten op dit niveau zijn:
. de keuze van de codering van de informatie (analoog of digitaal)
. de keuze van de transmissiemodus (synchroon of asynchroon).
Liaison de données
Verbergt de fysieke kenmerken van de fysieke laag. Detecteert en corrigeert transmissiefouten.
Réseau
Beheert het pad dat de via het netwerk verzonden informatie moet volgen. Dit wordt de routage genoemd: het bepalen van de route die informatie moet volgen om bij de ontvanger aan te komen.
Transport
Maakt communicatie tussen twee applicaties mogelijk, terwijl de voorgaande lagen alleen communicatie tussen machines toelieten. Een dienst die door deze laag wordt geleverd, kan multiplexing zijn: de transportlaag kan één en dezelfde netwerkverbinding (van machine naar machine) gebruiken om informatie van meerdere applicaties te verzenden.
Session
In deze laag vinden we diensten waarmee een applicatie een werksessie op een externe machine kan openen en in stand houden.
Présentation
Deze laag heeft tot doel de weergave van gegevens op de verschillende machines te uniformiseren. Zo worden gegevens afkomstig van machine A door de Présentation-laag van machine A in een standaardformaat ‘verpakt’ voordat ze over het netwerk worden verzonden. Zodra de gegevens de laag Présentation van de ontvangende machine B bereiken – die ze dankzij hun standaardformaat herkent – worden ze op een andere manier verpakt, zodat de applicatie van machine B ze kan herkennen.
Application
Op dit niveau bevinden zich de toepassingen die doorgaans dicht bij de gebruiker staan, zoals e-mail of bestandsoverdracht.

2.6.2. Het model TCP/IP

Het model OSI is een ideaal model. De reeks protocollen TCP/IP komt hier dicht bij in de volgende vorm:

Image

  • de netwerkinterface (de netwerkkaart van de computer) vervult de functies van de lagen 1 en 2 van het model OSI
  • de laag IP (Internet Protocol) vervult de functies van laag 3 (netwerk)
  • de laag TCP (Transfer Control Protocol) of UDP (User Datagram Protocol) vervult de functies van laag 4 (transport). Het protocol TCP zorgt ervoor dat de gegevenspakketten die door de computers worden uitgewisseld, daadwerkelijk op hun bestemming aankomen. Als dat niet het geval is, stuurt het de verdwaalde pakketten terug. Het protocol UDP doet dit niet en het is dan aan de applicatieontwikkelaar om dit te doen. Daarom wordt op het internet, dat geen 100% betrouwbaar netwerk is, het protocol TCP het meest gebruikt. We spreken dan van een TCP-IP-netwerk.
  • De applicatielaag omvat de functies van de niveaus 5 tot en met 7 van het OSI-model.

Webapplicaties bevinden zich in de Application-laag en maken dus gebruik van de TCP-IP-protocollen. De Application-lagen van de client- en servercomputers wisselen berichten uit die aan de lagen 1 tot en met 4 van het model worden toevertrouwd om naar de bestemming te worden doorgestuurd. Om elkaar te kunnen begrijpen, moeten de applicatielagen van beide computers dezelfde taal of hetzelfde protocol „spreken”. Dat van de webapplicaties heet HTTP (HyperText Transfer Protocol). Het is een tekstprotocol, c.a.d, waarbij de machines tekstregels over het netwerk uitwisselen om elkaar te begrijpen. Deze uitwisselingen zijn gestandaardiseerd, c.a.d, wat betekent dat de client over een aantal berichten beschikt om de server precies aan te geven wat hij wil, en dat de server eveneens over een aantal berichten beschikt om de client zijn antwoord te geven. Deze uitwisseling van berichten heeft de volgende vorm:

Image

Client --> Server

Wanneer de client een verzoek indient bij de webserver, stuurt hij

  1. tekstregels in het formaat HTTP om aan te geven wat hij wil
  1. een lege regel
  2. eventueel een document

Server --> Client

Wanneer de server zijn antwoord naar de klant stuurt, verzendt hij

  1. tekstregels in het formaat HTTP om aan te geven wat hij verstuurt
  2. een lege regel
  3. optioneel een document

De uitwisselingen hebben dus in beide richtingen dezelfde vorm. In beide gevallen kan er een document worden verzonden, ook al komt het zelden voor dat een client een document naar de server stuurt. Maar het protocol HTTP voorziet hierin. Hierdoor kunnen bijvoorbeeld abonnees van een internetprovider diverse documenten uploaden naar hun persoonlijke website die bij deze provider wordt gehost. De uitgewisselde documenten kunnen van welke aard dan ook zijn. Laten we eens kijken naar een browser die een webpagina met afbeeldingen opvraagt:

  1. de browser maakt verbinding met de webserver en vraagt de gewenste pagina op. De opgevraagde bronnen worden op unieke wijze aangeduid door middel van URL (Uniform Resource Locator). De browser verstuurt alleen HTTP-headers en geen documenten.
  2. De server antwoordt. Hij stuurt eerst HTTP-headers waarin wordt aangegeven welk type antwoord hij verstuurt. Dit kan een foutmelding zijn als de opgevraagde pagina niet bestaat. Als de pagina wel bestaat, geeft de server in de HTTP-headers van zijn antwoord aan dat hij na deze headers een HTML-document (HyperText Markup Language) zal verzenden. Dit document bestaat uit een reeks tekstregels in het HTML-formaat. Een HTML-tekst bevat tags (markeringen) die de browser aanwijzingen geven over de manier waarop de tekst moet worden weergegeven.
  3. De client weet aan de hand van de HTTP-headers van de server dat hij een HTML-document zal ontvangen. Hij analyseert dit document en merkt wellicht op dat het verwijzingen naar afbeeldingen bevat. Deze afbeeldingen staan niet in het document HTML. Daarom doet hij een nieuw verzoek aan dezelfde webserver om de eerste afbeelding op te vragen die hij nodig heeft. Dit verzoek is identiek aan dat in stap 1, behalve dat de opgevraagde bron anders is. De server verwerkt dit verzoek door de gevraagde afbeelding naar de client te sturen. Deze keer geven de headers van het antwoord op HTTP aan dat het verzonden document een afbeelding is en geen document met de naam HTML.
  4. De client haalt de verzonden afbeelding op. De stappen 3 en 4 worden herhaald totdat de client (meestal een browser) alle documenten heeft ontvangen die nodig zijn om de volledige pagina weer te geven.

2.6.3. Het protocol HTTP

Laten we het protocol HTTP aan de hand van voorbeelden bekijken. Wat wisselen een browser en een webserver uit?

2.6.3.1. Het antwoord van een HTTP-server

We gaan hier ontdekken hoe een webserver reageert op verzoeken van zijn klanten. De webservice of HTTP-service is een TCP-IP-service die gewoonlijk op poort 80 draait. Hij zou ook op een andere poort kunnen draaien. In dat geval zou de browser van de klant deze poort moeten specificeren in de URL die hij opvraagt. Een URL heeft de volgende algemene vorm:

protocole://machine[:port]/pad/info

met

protocol
http voor de webservice. Een browser kan ook als client fungeren voor ftp-, news-, telnet- en andere diensten.
machine
naam van de machine waarop de webservice draait
poort
poort van de webservice. Als dit 80 is, kan het poortnummer worden weggelaten. Dit is het meest voorkomende geval
pad
pad naar de opgevraagde bron
info
aanvullende informatie die aan de server wordt verstrekt om het verzoek van de client te verduidelijken

Wat doet een browser wanneer een gebruiker vraagt om een URL te laden?

  1. Hij opent een TCP-IP-verbinding met de machine en de poort die zijn aangegeven in het machine[:port]-gedeelte van het URL-bestand. Het openen van een TCP-IP-verbinding betekent dat er een „communicatiekanaal” tussen twee machines wordt gecreëerd. Zodra dit kanaal is gecreëerd, verloopt alle informatie-uitwisseling tussen de twee machines hierdoorheen. Het aanmaken van deze verbinding TCP-IP houdt nog niet het webprotocol HTTP in.
  2. Zodra de TCP-IP-verbinding is aangemaakt, zal de client zijn verzoek naar de webserver sturen door tekstregels (commando’s) in het HTTP-formaat te verzenden. Hij zal het pad/informatiegedeelte van de URL naar de server sturen
  3. De server zal op dezelfde manier en via dezelfde verbinding antwoorden
  4. een van beide partijen besluit de verbinding te verbreken. Dit hangt af van het gebruikte protocol HTTP. Bij het protocol HTTP 1.0 sluit de server de verbinding na elk van zijn antwoorden. Dit dwingt een client die meerdere verzoeken moet doen om de verschillende documenten te verkrijgen waaruit een webpagina bestaat, om bij elk verzoek een nieuwe verbinding te openen, wat kosten met zich meebrengt. Met het protocol HTTP/1.1 kan de client de server opdragen de verbinding open te houden totdat hij aangeeft deze te sluiten. Hij kan dus alle documenten van een webpagina met één enkele verbinding ophalen en de verbinding zelf afsluiten zodra het laatste document is ontvangen. De server detecteert deze afsluiting en sluit de verbinding eveneens af.

Om de communicatie tussen een client en een webserver te bekijken, gaan we een tool gebruiken die ‘curl’ heet. Curl is een applicatie waarmee je als client gebruik kunt maken van internetdiensten die verschillende protocollen ondersteunen (DOS, FTP, TELNET, GOPHER, ...). curl is beschikbaar op http://curl.haxx.se/. We downloaden hier bij voorkeur de Windows-versie win32-nossl, aangezien de win32-ssl-versie extra DLL-bestanden vereist die niet in het curl-pakket zijn opgenomen. Dit pakket bevat een reeks bestanden die u alleen maar hoeft uit te pakken in een map die we voortaan <curl> zullen noemen. Deze map bevat een uitvoerbaar bestand met de naam [curl.exe]. Dit wordt onze client om webservers te benaderen. Laten we een DOS-venster openen en naar de map <curl> gaan:

dos>dir curl.exe
22/03/2004  13:29              299 008 curl.exe

E:\curl2>curl
curl: try 'curl --help' for more information
dos>curl --help | more
Usage: curl [options...] <url>
Options: (H) means HTTP/HTTPS only, (F) means FTP only
 -a/--append        Append to target file when uploading (F)
 -A/--user-agent <string> User-Agent to send to server (H)
    --anyauth       Tell curl to choose authentication method (H)
 -b/--cookie <name=string/file> Cookie string or file to read cookies from (H)
    --basic         Enable HTTP Basic Authentication (H)
 -B/--use-ascii     Use ASCII/text transfer
 -c/--cookie-jar <file> Write cookies to this file after operation (H)
 ....

Laten we deze applicatie gebruiken om een webserver te bevragen en de communicatie tussen de client en de server te bekijken. We bevinden ons in de volgende situatie:

Image

De webserver kan willekeurig zijn. We willen hier de communicatie in kaart brengen die plaatsvindt tussen de curl-webclient en de webserver. Eerder hebben we de volgende statische pagina HTML aangemaakt:

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

die we in een browser bekijken:

Image

We zien dat de opgevraagde URL: http://localhost/aspnet/chap1/statique1.html is. De server van de webservice is dus localhost (=lokale server) en poort 80. Als we de brontekst van deze webpagina (Weergave/Bron) bekijken, vinden we de oorspronkelijk aangemaakte tekst terug:

Image

Laten we nu onze client CURL gebruiken om dezelfde URL op te vragen:

dos>curl http://localhost/aspnet/chap1/statique1.html
<html>
  <head>
    <title>essai 1 : une page statique</title>
   </head>
   <body>
     <center>
     <h1>Une page statique...</h1>
   </body>
</html>

We zien dat de webserver een reeks tekstregels heeft teruggestuurd die de code HTML van de opgevraagde pagina vertegenwoordigt. We hebben eerder gezegd dat het antwoord van een webserver de volgende vorm heeft:

Image

Maar hier hebben we de headers HTTP niet gezien. Dit komt doordat [curl] deze standaard niet weergeeft. Met de optie --include kun je ze weergeven:

E:\curl2>curl --include http://localhost/aspnet/chap1/statique1.html
HTTP/1.1 200 OK
Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
Date: Mon, 22 Mar 2004 16:51:00 GMT
X-AspNet-Version: 1.1.4322
Cache-Control: public
ETag: "1C4102CEE8C6400:1C4102CFBBE2250"
Content-Type: text/html
Content-Length: 161
Connection: Close

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

De server heeft inderdaad een reeks HTTP-headers verzonden, gevolgd door een lege regel:

HTTP/1.1 200 OK
Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
Date: Mon, 22 Mar 2004 16:51:00 GMT
X-AspNet-Version: 1.1.4322
Cache-Control: public
ETag: "1C4102CEE8C6400:1C4102CFBBE2250"
Content-Type: text/html
Content-Length: 161
Connection: Close
HTTP/1.1 200 OK
de server geeft aan
  • dat hij het protocol HTTP versie 1.1 ondersteunt
  • dat hij de gevraagde bron heeft (code 200, bericht OK)
Server: 
de server identificeert zich. In dit geval is het een Cassini-server
Date: ...
de datum/tijd van het antwoord
X-ASPNet-Version: ...
specifieke header voor de Cassini-server
Cache-Control: public
geeft de client aan of het antwoord dat naar hem wordt verzonden in de cache kan worden opgeslagen. Het attribuut [public] geeft de client aan dat hij de pagina in de cache mag opslaan. Een attribuut [no-cache] zou de client hebben aangegeven dat hij de pagina niet in de cache mocht opslaan.
ETag:
...
Content-type: text/html
de server geeft aan dat hij tekst (text) gaat verzenden in het formaat HTML (html).
Content-Length: 161
aantal bytes van het document dat na de headers HTTP wordt verzonden. Dit getal is in feite de grootte in bytes van het bestand essai1.html:
dos>dir essai1.html

08/07/2002  10:00                  161 essai1.html
Connection: close
de server geeft aan dat hij de verbinding zal verbreken zodra het document is verzonden

De client ontvangt deze headers HTTP en weet nu dat hij 161 bytes zal ontvangen die een document HTML vertegenwoordigen. De server verstuurt deze 161 bytes onmiddellijk na de lege regel die het einde van de headers HTTP aangaf:

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

Hier herkennen we het oorspronkelijk aangemaakte bestand HTML. Als onze client een browser was, zou deze na ontvangst van deze tekstregels deze interpreteren om de gebruiker via het toetsenbord de volgende pagina te tonen:

Image

Laten we onze client [curl] nogmaals gebruiken om dezelfde bron op te vragen, maar deze keer alleen de headers van het antwoord opvragen:

dos>curl --head http://localhost/aspnet/chap1/statique1.html
HTTP/1.1 200 OK
Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
Date: Tue, 23 Mar 2004 07:11:54 GMT
Cache-Control: public
ETag: "1C410A504D60680:1C410A58621AD3E"
Content-Type: text/html
Content-Length: 161
Connection: Close

We krijgen hetzelfde resultaat als eerder, zonder het document HTML. Laten we nu zowel met een browser als met de generieke client TCP een afbeelding opvragen. Eerst met een browser:

Image

Het bestand univ01.gif is 4052 bytes groot:

dos>dir univ01.gif
23/03/2004  08:14             4 052 univ01.gif

Laten we nu de client [curl] gebruiken:

dos>curl --head http://localhost/aspnet/chap1/univ01.gif
HTTP/1.1 200 OK
Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
Date: Tue, 23 Mar 2004 07:18:44 GMT
Cache-Control: public
ETag: "1C410A6795D7500:1C410A6868B1476"
Content-Type: image/gif
Content-Length: 4052
Connection: Close

In de bovenstaande vraag-antwoordcyclus vallen de volgende punten op:

--head
  • we vragen alleen de headers HTTP van de bron op. Een afbeelding is namelijk een binair bestand en geen tekstbestand, en de weergave ervan op het scherm als tekst levert geen leesbare tekst op.
Content-Length: 4052
  • dit is de bestandsgrootte univ01.gif
Content-Type: image/gif
  • De server laat zijn client weten dat hij hem een document van het type image/gif, c.a.d en een afbeelding in het formaat GIF gaat sturen. Als de afbeelding het formaat JPEG had gehad, zou het documenttype image/jpeg zijn geweest. De documenttypes zijn gestandaardiseerd en worden MIME-types (Multi-purpose Mail Internet Extension) genoemd.

2.6.3.2. Het verzoek van een client HTTP

Laten we ons nu de volgende vraag stellen: als we een programma willen schrijven dat met een webserver „communiceert”, welke commando’s moet het dan naar de webserver sturen om een bepaalde bron op te halen? In de voorgaande voorbeelden hebben we gezien wat de client ontving, maar niet wat de client verstuurde. We gaan de optie [--verbose] van curl gebruiken om ook te zien wat de client naar de server verstuurt. Laten we beginnen met het opvragen van de statische pagina:

dos>curl --verbose http://localhost/aspnet/chap1/statique1.html
* About to connect() to localhost:80
* Connected to portable1_tahe (127.0.0.1) port 80
> GET /aspnet/chap1/statique1.html HTTP/1.1
User-Agent: curl/7.10.8 (win32) libcurl/7.10.8 OpenSSL/0.9.7a zlib/1.1.4
Host: localhost
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

< HTTP/1.1 200 OK
< Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
< Date: Tue, 23 Mar 2004 07:37:06 GMT
< Cache-Control: public
< ETag: "1C410A504D60680:1C410A58621AD3E"
< Content-Type: text/html
< Content-Length: 161
< Connection: Close
<html>
  <head>
    <title>essai 1 : une page statique</title>
   </head>
   <body>
     <center>
     <h1>Une page statique...</h1>
   </body>
</html>
* Closing connection #0

Allereerst brengt de client [curl] een TCP/IP-verbinding tot stand met poort 80 van de machine localhost (=127.0.0.1)

* About to connect() to localhost:80
* Connected to portable1_tahe (127.0.0.1) port 80

Zodra de verbinding tot stand is gebracht, verstuurt hij zijn verzoek HTTP. Dit is een reeks tekstregels die eindigt met een lege regel:

GET /aspnet/chap1/statique1.html HTTP/1.1
User-Agent: curl/7.10.8 (win32) libcurl/7.10.8 OpenSSL/0.9.7a zlib/1.1.4
Host: localhost
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

De aanvraag HTTP van een webclient heeft twee functies:

  • de gewenste bron aangeven. Dit is hier de rol van de eerste regel GET
  • informatie verstrekken over de client die het verzoek indient, zodat de server zijn antwoord eventueel kan aanpassen aan dit specifieke type client.

De betekenis van de hierboven door de client verzonden regels [curl] is als volgt:

GET ressource protocole
om een bepaalde bron op te vragen volgens een bepaalde versie van het protocol HTTP. De server stuurt een antwoord in het formaat HTTP, gevolgd door een lege regel en vervolgens de gevraagde bron
User-Agent
om aan te geven wie de client is
host: machine:port
om (protocol HTTP 1.1) de machine en de poort van de opgevraagde webserver te specificeren
Pargma
hier om aan te geven dat de klant geen cache beheert.
Accept
types MIME om aan te geven welke bestandstypen de client kan verwerken

Laten we de bewerking opnieuw uitvoeren met de optie --head van [curl]:

dos>curl --verbose --head --output reponse.txt http://localhost/aspnet/chap1/statique1.html
* About to connect() to localhost:80
* Connected to portable1_tahe (127.0.0.1) port 80
> HEAD /aspnet/chap1/statique1.html HTTP/1.1
User-Agent: curl/7.10.8 (win32) libcurl/7.10.8 OpenSSL/0.9.7a zlib/1.1.4
Host: localhost
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

< HTTP/1.1 200 OK
< Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
< Date: Tue, 23 Mar 2004 07:54:22 GMT
< Cache-Control: public
< ETag: "1C410A504D60680:1C410A58621AD3E"
< Content-Type: text/html
< Content-Length: 161
< Connection: Close

We richten ons alleen op de door de klant verzonden headers HTTP:

HEAD /aspnet/chap1/statique1.html HTTP/1.1
User-Agent: curl/7.10.8 (win32) libcurl/7.10.8 OpenSSL/0.9.7a zlib/1.1.4
Host: localhost
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

Alleen de opdracht waarmee de bron wordt opgevraagd, is gewijzigd. In plaats van een verzoek GET hebben we nu een verzoek HEAD. Dit verzoek vraagt dat het antwoord van de server beperkt blijft tot de headers HTTP en dat de gevraagde bron niet wordt verzonden. Op de bovenstaande schermafbeelding worden de ontvangen HTTP-headers niet weergegeven. Deze zijn in een bestand opgeslagen vanwege de optie [--output reponse.txt] van het commando [curl]:

dos>more reponse.txt
HTTP/1.1 200 OK
Server: Microsoft ASP.NET Web Matrix Server/0.6.0.0
Date: Tue, 23 Mar 2004 07:54:22 GMT
Cache-Control: public
ETag: "1C410A504D60680:1C410A58621AD3E"
Content-Type: text/html
Content-Length: 161
Connection: Close

2.6.4. Conclusie

Aan de hand van enkele voorbeelden hebben we de structuur van het verzoek van een webclient en die van het antwoord van de webserver hierop bekeken. De communicatie verloopt via het protocol HTTP, een reeks tekstcommando’s die door beide partijen worden uitgewisseld. Het verzoek van de client en het antwoord van de server hebben beide de volgende structuur:

Image

Bij een verzoek (vaak ‘request’ genoemd) van de client ontbreekt het gedeelte [Document] meestal. Het is echter mogelijk dat een client een document naar de server verstuurt. Dit gebeurt met een commando genaamd PUT. De twee gebruikelijke commando’s om een bron op te vragen zijn GET en POST. Dit laatste commando wordt iets verderop toegelicht. Met het commando HEAD kunnen alleen de headers HTTP worden opgevraagd. De commando’s GET en POST worden het meest gebruikt door webclients van het browsertype.

Op verzoek van een client stuurt de server een antwoord met dezelfde structuur. De opgevraagde bron wordt verzonden in het gedeelte [Document], tenzij de opdracht van de client HEAD was; in dat geval worden alleen de headers HTTP verzonden.

2.7. De taal HTML

Een webbrowser kan verschillende documenten weergeven, waarvan het meest gangbare het HTML-document is (HyperText Markup Language). Dit is een tekst die is opgemaakt met tags in de vorm <balise>texte</balise>. Zo zal de tekst <B>important</B> de belangrijke tekst vetgedrukt weergeven. Er bestaan ook op zichzelf staande tags, zoals de tag <hr>, die een horizontale lijn weergeeft. We zullen niet ingaan op de tags die in een tekst HTML kunnen voorkomen. Er bestaat veel WYSIWYG-software waarmee je een webpagina kunt bouwen zonder ook maar één regel HTML-code te schrijven. Deze tools genereren automatisch de HTML-code van een lay-out die met de muis en vooraf gedefinieerde besturingselementen is gemaakt. Zo kun je (met de muis) een tabel in de pagina invoegen en vervolgens de door de software gegenereerde HTML-code bekijken om te ontdekken welke tags je moet gebruiken om een tabel in een webpagina te definiëren. Eenvoudiger kan het niet. Bovendien is kennis van de taal HTML onmisbaar, aangezien dynamische webapplicaties zelf de HTML-code moeten genereren die naar de webclients moet worden verzonden. Deze code wordt programmatisch gegenereerd en men moet natuurlijk weten wat er moet worden gegenereerd, zodat de client de gewenste webpagina te zien krijgt.

Kortom, het is helemaal niet nodig om de volledige taal HTML te beheersen om met webprogrammeren te beginnen. Deze kennis is echter wel noodzakelijk en kan worden opgedaan door het gebruik van WYSIWYG-software voor het bouwen van webpagina’s, zoals Word, FrontPage, DreamWeaver en tientallen andere. Een andere manier om de fijne kneepjes van de taal HTML te ontdekken, is door op het web te surfen en de broncode te bekijken van pagina’s die interessante kenmerken vertonen die u nog niet kent.

2.7.1. Een voorbeeld

Laten we eens kijken naar het volgende voorbeeld, gemaakt met FrontPage Express, een gratis tool die bij Internet Explorer wordt geleverd. De door Frontpage gegenereerde code is hier opgeschoond. Dit voorbeeld toont enkele elementen die in een webdocument kunnen voorkomen, zoals:

  • een tabel
  • een afbeelding
  • een link

Image

Een HTML-document heeft de volgende algemene vorm:

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

Het gehele document wordt omgeven door de tags <html>...</html>. Het bestaat uit twee delen:

  1. <head>...</head>: dit is het niet-weergegeven gedeelte van het document. Het geeft informatie aan de browser die het document gaat weergeven. Hierin staat vaak de tag <title>...</title>, die de tekst vastlegt die in de titelbalk van de browser wordt weergegeven. Er kunnen ook andere tags in staan, met name tags die de trefwoorden van het document definiëren; trefwoorden die vervolgens door zoekmachines worden gebruikt. In dit gedeelte kunnen ook scripts voorkomen, meestal geschreven in JavaScript of VBScript, die door de browser worden uitgevoerd.
  2. <body attributen>...</body>: dit is het gedeelte dat door de browser wordt weergegeven. De tags HTML in dit gedeelte geven aan de browser aan hoe het document er visueel „uit moet zien”. Elke browser interpreteert deze tags op zijn eigen manier. Twee browsers kunnen hetzelfde webdocument dus op verschillende manieren weergeven. Dit is doorgaans een van de grootste uitdagingen voor webontwerpers.

De code HTML van ons voorbeelddocument is als volgt:

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

In de code zijn alleen de punten gemarkeerd die voor ons van belang zijn:

Element
tags en voorbeelden HTML
titre du document
<title>balises</title>
balises verschijnt in de titelbalk van de browser die het document weergeeft
barre horizontale
<hr>: geeft een horizontale streep weer
tableau
<table-attributen>....</table>: om de tabel te definiëren
<tr attributen>...</tr>: om een rij te definiëren
<td attributen>...</td>: om een cel te definiëren
voorbeelden:
<table border="1">...</table>: het attribuut border bepaalt de dikte van de rand van de tabel
<td valign="middle" align="center" width="150">cel(1,2)</td>: definieert een cel waarvan de inhoud cel(1,2) zal zijn. Deze inhoud wordt verticaal (valign="middle") en horizontaal (align="center") gecentreerd. De cel heeft een breedte van 150 pixels (width="150")
image
<img border="0" src="/images/univ01.gif" width="80" height="95">: definieert een afbeelding zonder rand (border="0"), met een hoogte van 95 pixels (height="95"), een breedte van 80 pixels (width="80") en waarvan het bronbestand zich op de webserver bevindt onder /images/univ01.gif (src="/images/univ01.gif"). Deze link staat in een webdocument dat is gegenereerd met de URL http://localhost:81/html/balises.htm. De browser zal dus de URL http://localhost:81/images/univ01.gif opvragen om de afbeelding te verkrijgen waarnaar hier wordt verwezen.
lien
<a href="http://istia.univ-angers.fr">hier</a>: zorgt ervoor dat de tekst ici als link naar de pagina URL http://istia.univ-angers.fr fungeert.
fond de page
<body background="/images/standard.jpg">: geeft aan dat de afbeelding die als achtergrond voor de pagina moet dienen, zich op de webserver bevindt op URL /images/standard.jpg. In het kader van ons voorbeeld zal de browser het bestand URL http://localhost:81/images/standard.jpg opvragen om deze achtergrondafbeelding op te halen.

Uit dit eenvoudige voorbeeld blijkt dat de browser, om het volledige document op te bouwen, drie verzoeken naar de server moet sturen:

  1. http://localhost:81/html/balises.htm om de broncode HTML van het document op te halen
  2. http://localhost:81/images/univ01.gif om de afbeelding univ01.gif op te halen
  3. http://localhost:81/images/standard.jpg om de achtergrondafbeelding standard.jpg op te halen

Het volgende voorbeeld toont een webformulier dat eveneens is gemaakt met FrontPage.

Image

De door FrontPage gegenereerde en enigszins opgeschoonde code HTML is als volgt:

<html>

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

De visuele controle <--> tag HTML is als volgt:

Controle
tag HTML
formulaire
<form method="POST" >
champ de saisie
<input type="text" name="txtSaisie" size="20" value="een paar woorden">
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">
regel1
regel2
regel3
</textarea>
boutons radio
<input type="radio" value="Ja" name="R1">Ja
<input type="radio" name="R1" value="nee" checked>Nee
cases à cocher
<input type="checkbox" name="C1" value="één">1
<input type="checkbox" name="C2" value="twee" checked>2
<input type="checkbox" name="C3" value="drie">3
Combo
<select size="1" name="cmbValeurs">
<option>keuze1</option>
<option selected>keuze2</option>
<option>keuze3</option>
</select>
liste à sélection unique
<select size="3" name="lst1">
<option selected>lijst1</option>
<option>lijst2</option>
<option>lijst3</option>
<option>lijst4</option>
<option>lijst5</option>
</select>
liste à sélection multiple
<select size="3" name="lst2" multiple>
<option>lijst1</option>
<option>lijst2</option>
<option selected>lijst3</option>
<option>lijst4</option>
<option>lijst5</option>
</select>
bouton de type submit
<input type="submit" value="Verzenden" name="cmdRenvoyer">
bouton de type reset
<input type="reset" value="Resetten" name="cmdRétablir">
bouton de type button
<input type="button" value="Wissen" name="cmdEffacer" onclick="effacer()">

Laten we deze verschillende besturingselementen eens bekijken.

2.7.1.1. Het formulier

formulaire
<form method="POST" >
balise HTML
<form name="..." method="..." action="...">...</form>
attributs
name="frmexemple": naam van het formulier
method="..." : methode die door de browser wordt gebruikt om de in het formulier verzamelde waarden naar de webserver te verzenden
action="..." : URL waarnaar de in het formulier verzamelde waarden worden verzonden.
Een webformulier wordt omgeven door de <form>...</form>-tags. Het formulier kan een naam hebben (name="xx"). Dit geldt voor alle besturingselementen die in een formulier voorkomen. Deze naam is nuttig als het webdocument scripts bevat die naar elementen van het formulier moeten verwijzen. Het doel van een formulier is om informatie te verzamelen die de gebruiker via het toetsenbord of de muis invoert, en deze naar een URL van een webserver te verzenden. Welke? Die waarnaar wordt verwezen in het attribuut action="URL". Als dit attribuut ontbreekt, wordt de informatie verzonden naar de URL van het document waarin het formulier zich bevindt. Dat zou het geval zijn in het bovenstaande voorbeeld. Tot nu toe hebben we de webclient altijd gezien als een entiteit die informatie „opvraagt” bij een webserver, nooit als een entiteit die informatie „verstrekt” aan een webserver. Hoe zorgt een webclient ervoor dat hij informatie (die in het formulier staat) aan een webserver verstrekt? We zullen hier later in detail op terugkomen. Hij kan twee verschillende methoden gebruiken, namelijk POST en GET. Het attribuut method="méthode", met als methode GET of POST, van de tag <form> geeft aan de browser aan welke methode moet worden gebruikt om de in het formulier verzamelde informatie te verzenden naar de URL die is opgegeven door het attribuut action="URL". Wanneer het attribuut method niet is opgegeven, wordt standaard de methode GET gebruikt.

2.7.1.2. Invoerveld

Image

Image

champ de saisie
<input type="text" name="txtSaisie" size="20" value="een paar woorden">
<input type="password" name="txtMdp" size="20" value="unMotDePasse">
balise HTML
<input type="..." name="..." size=".." value="..">
De input-tag bestaat voor verschillende besturingselementen. Het is het attribuut type waarmee deze verschillende besturingselementen van elkaar kunnen worden onderscheiden.
attributs
type="text": geeft aan dat het een invoerveld is
type="password": de tekens in het invoerveld worden vervangen door sterretjes (*). Dit is het enige verschil met het normale invoerveld. Dit type besturingselement is geschikt voor het invoeren van wachtwoorden.
size="20": aantal zichtbare tekens in het veld – dit belet niet dat er meer tekens worden ingevoerd
name="txtSaisie": naam van het invoerveld
value="een paar woorden": tekst die in het invoerveld wordt weergegeven.

2.7.1.3. Invoerveld met meerdere regels

Image

champ de saisie multilignes
<textarea rows="2" name="areaSaisie" cols="20">
ligne1
ligne2
ligne3
</textarea>
balise HTML
<textarea ...>tekst</textarea>
geeft een invoerveld voor meerdere regels weer met aanvankelijk tekst erin
attributs
rows="2": aantal regels
cols="'20": aantal kolommen
name="areaSaisie": naam van het besturingselement

2.7.1.4. Keuzerondjes

Image

boutons radio
<input type="radio" value="Ja" name="R1">Ja
<input type="radio" name="R1" value="nee" checked>Nee
balise HTML
<input type="radio" attribuut2="waarde2" ....>tekst
toont een keuzerondje met tekst ernaast.
attributs
name="radio": naam van het besturingselement. Keuzerondjes met dezelfde naam vormen een groep die elkaar uitsluiten: er kan slechts één worden aangevinkt.
value="waarde": waarde die aan de keuzeknop wordt toegewezen. Deze waarde mag niet worden verward met de tekst die naast de keuzeknop wordt weergegeven. Deze tekst is uitsluitend bedoeld voor weergave.
checked: als dit trefwoord aanwezig is, is de keuzeknop aangevinkt, anders niet.

2.7.1.5. Selectievakjes

cases à cocher
<input type="checkbox" name="C1" value="één">1
<input type="checkbox" name="C2" value="twee" checked>2
<input type="checkbox" name="C3" value="drie">3

Image

balise HTML
<input type="checkbox" attribuut2="waarde2" ....>tekst
toont een selectievakje met tekst ernaast.
attributs
name="C1": naam van het besturingselement. Selectievakjes kunnen al dan niet dezelfde naam hebben. Selectievakjes met dezelfde naam vormen een groep van aan elkaar gekoppelde selectievakjes.
value="waarde": waarde die aan het selectievakje wordt toegewezen. Deze waarde mag niet worden verward met de tekst die naast het selectievakje wordt weergegeven. Deze tekst is uitsluitend bedoeld voor weergave.
checked: als dit trefwoord aanwezig is, is het keuzerondje aangevinkt, anders niet.

2.7.1.6. Keuzelijst (combo)

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

Image

balise HTML
<select size=".." name="..">
<option [selected]>...</option>
...
</select>
geeft in een lijst de teksten weer die tussen de tags <option>...</option> staan
attributs
name="cmbValeurs": naam van het besturingselement.
size="1": aantal zichtbare lijstitems. size="1" zorgt ervoor dat de lijst functioneert als een combobox.
selected: als dit trefwoord voor een lijstitem aanwezig is, wordt dit item in de lijst als geselecteerd weergegeven. In ons voorbeeld hierboven wordt het lijstitem choix2 weergegeven als het geselecteerde item van de combobox wanneer deze voor het eerst wordt weergegeven.

2.7.1.7. Lijst met één selectie

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

Image

balise HTML
<select size=".." name="..">
<option [selected]>...</option>
...
</select>
geeft in een lijst de teksten weer die tussen de tags <option>...</option> staan
attributs
dezelfde als voor de vervolgkeuzelijst die slechts één item weergeeft. Dit besturingselement verschilt alleen van de vorige vervolgkeuzelijst door het attribuut size>1.

2.7.1.8. Lijst met meerdere selecties

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

Image

balise HTML
<select size=".." name=".." multiple>
<option [selected]>...</option>
...
</select>
geeft in een lijst de teksten weer die tussen de tags <option>...</option> staan
attributs
multiple: maakt het mogelijk om meerdere elementen in de lijst te selecteren. In het bovenstaande voorbeeld zijn de elementen liste1 en liste3 beide geselecteerd.

2.7.1.9. Knop van het type button

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

Image

balise HTML
<input type="button" value="..." name="..." onclick="effacer()" ....>
attributs
type="button": definieert een knop. Er zijn nog twee andere soorten knoppen: de typen submit en reset.
value="Wissen": de tekst die op de knop wordt weergegeven
onclick="functie()": hiermee kunt u een functie definiëren die moet worden uitgevoerd wanneer de gebruiker op de knop klikt. Deze functie maakt deel uit van de scripts die in het weergegeven webdocument zijn gedefinieerd. De bovenstaande syntaxis is een javascript-syntaxis. Als de scripts in VBScript zijn geschreven, moet u onclick="functie" schrijven zonder de haakjes. De syntaxis blijft hetzelfde als er parameters aan de functie moeten worden doorgegeven: onclick="functie(val1, val2,...)"
In ons voorbeeld roept een klik op de knop Effacer de volgende JavaScript-functie effacer aan:
    <script language="JavaScript">
        function effacer(){
          alert("Vous avez cliqué sur le bouton Effacer");
      }//verwijderen
        </script>
De functie effacer geeft het volgende bericht weer:

2.7.1.10. Submit-knop

bouton de type submit
<input type="submit" value="Verzenden" name="cmdRenvoyer">

Image

balise HTML
<input type="submit" value="Verzenden" name="cmdRenvoyer">
attributs
type="submit": definieert de knop als een knop om de gegevens van het formulier naar de webserver te verzenden. Wanneer de gebruiker op deze knop klikt, verzendt de browser de gegevens van het formulier naar de URL die is gedefinieerd in het attribuut action van de tag <form>, volgens de methode die is gedefinieerd door het attribuut method van diezelfde tag.
value="Verzenden": de tekst die op de knop wordt weergegeven

2.7.1.11. Resetknop

bouton de type reset
<input type="reset" value="Resetten" name="cmdRétablir">

Image

balise HTML
<input type="reset" value="Terugzetten" name="cmdRétablir">
attributs
type="reset": definieert de knop als een knop om het formulier te resetten. Wanneer de gebruiker op deze knop klikt, zet de browser het formulier terug in de staat waarin het werd ontvangen.
value="Resetten" : de tekst die op de knop wordt weergegeven

2.7.1.12. Verborgen veld

champ caché
<input type="hidden" name="secret" value="uneValeur">
balise HTML
<input type="hidden" name="..." value="...">
attributs
type="hidden": geeft aan dat het een verborgen veld is. Een verborgen veld maakt deel uit van het formulier, maar wordt niet aan de gebruiker getoond. Als de gebruiker echter aan zijn browser zou vragen om de broncode weer te geven, zou hij de tag <input type="hidden" value="..."> zien en dus ook de waarde van het verborgen veld.
value="eenWaarde": waarde van het verborgen veld.
Wat is het nut van het verborgen veld? Hiermee kan de webserver informatie bijhouden tijdens de verzoeken van een klant. Laten we eens kijken naar een online winkelapplicatie. De klant koopt een eerste artikel art1 in een hoeveelheid q1 op een eerste pagina van een catalogus en gaat vervolgens naar een nieuwe pagina van de catalogus. Om te onthouden dat de klant q1 artikelen art1 heeft gekocht, kan de server deze twee gegevens in een verborgen veld van het webformulier op de nieuwe pagina plaatsen. Op deze nieuwe pagina koopt de klant de artikelen q2 en art2. Wanneer de gegevens van dit tweede formulier naar de server worden verzonden (submit), ontvangt de server niet alleen de informatie (q2,art2), maar ook (q1,art1), die eveneens deel uitmaakt van het formulier als een verborgen veld dat niet door de gebruiker kan worden gewijzigd. De webserver zal vervolgens de gegevens (q1,art1) en (q2,art2) in een nieuw verborgen veld plaatsen en een nieuwe cataloguspagina verzenden. En zo verder.

2.7.2. Verzending van formulierwaarden naar een webserver door een webclient

In de vorige studie hebben we gezegd dat de webclient over twee methoden beschikt om de waarden van een formulier dat hij heeft weergegeven naar een webserver te verzenden: de methoden GET en POST. Laten we aan de hand van een voorbeeld het verschil tussen beide methoden bekijken. De pagina die we eerder hebben bestudeerd, is een statische pagina. Om toegang te krijgen tot de HTTP-headers die worden verzonden door de browser die dit document opvraagt, maken we er een dynamische pagina van voor een .NET-webserver (IIS of Cassini). Het gaat hier niet om de .NET-technologie, die in het volgende hoofdstuk aan bod komt, maar om de communicatie tussen client en server. De code van de pagina ASP.NET is als volgt:

<%@ Page Language="vb" CodeBehind="params.aspx.vb" AutoEventWireup="false" Inherits="ConsoleApplication1.params" %>
<script runat="server">

    Private Sub Page_Init(Byval Sender as Object, Byval e as System.EventArgs)
       ' de query wordt opgeslagen
    saveRequest
  end sub
  Private Sub saveRequest
       ' slaat de huidige aanvraag op in request.txt in de map van de pagina
    dim requestFileName as String=Me.MapPath(Me.TemplateSourceDirectory)+"\request.txt"
    Me.Request.SaveAs(requestFileName,true)
  end sub
</script>

<html>
    <head>
        <title>balises</title>
        <script language="JavaScript">
        function effacer(){
          alert("Vous avez cliqué sur le bouton Effacer");
      }//verwijderen
        </script>
    </head>
    <body background="/images/standard.jpg">
....
    </body>
</html>

Aan de inhoud HTML van de onderzochte pagina voegen we een stukje code toe in VB.NET. We zullen deze code niet toelichten, behalve om te vermelden dat bij elke oproep van het bovenstaande document de webserver het verzoek van de webklant zal opslaan in het bestand [request.txt] in de map van het opgeroepen document.

2.7.2.1. Methode GET

Laten we een eerste test uitvoeren, waarbij in de code HTML van het document de tag FORM als volgt is gedefinieerd:


        <form method="get">

Het voorgaande document (HTML + code VB) wordt [params.aspx] genoemd. Het wordt in de boomstructuur van een webserver .NET (IIS/Cassini) geplaatst en opgeroepen via de URL http://localhost/aspnet/chap1/params.aspx:

Image

De browser heeft zojuist een verzoek verzonden en we weten dat dit is opgeslagen in het bestand [request.txt]. Laten we de inhoud ervan eens bekijken:

GET /aspnet/chap1/params.aspx HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113

We zien elementen terug die we al eerder bij de klant [curl] zijn tegengekomen. Andere elementen verschijnen voor het eerst:

Connection: keep-alive
de client vraagt de server om de verbinding na zijn antwoord niet te verbreken. Hierdoor kan hij dezelfde verbinding gebruiken voor een volgend verzoek. De verbinding blijft niet onbeperkt openstaan. De server verbreekt deze na een te lange periode van inactiviteit.
Keep-Alive
de duur in seconden gedurende welke de verbinding [Keep-Alive] open blijft
Accept-Charset
Categorie tekens die de client kan verwerken
Accept-Language
Lijst met de voorkeurstalen van de klant.

We vullen het formulier als volgt in:

Image

We gebruiken de bovenstaande knop [Envoyer]. De code HTML is als volgt:

<form method="get">
    ...
    <input type="submit" value="Envoyer">
    ...
</form>

Bij het klikken op een knop van het type [Submit], stuurt de browser de formulierparameters (tag <form>) naar de URL die is opgegeven in het attribuut [action] van de tag <form action="URL">, indien deze bestaat. Als dit attribuut niet bestaat, worden de formulierparameters verzonden naar de URL die het formulier heeft gegenereerd. Dat is hier het geval. De knop [Envoyer] zou dus moeten leiden tot een verzoek van de browser aan de URL [http://localhost/aspnet/chap1/params.aspx], waarbij de formulierparameters worden doorgegeven. Aangezien de pagina [params.aspx] het ontvangen verzoek onthoudt, zouden we moeten weten hoe de client deze parameters heeft doorgegeven. Laten we het eens proberen. We klikken op de knop [Envoyer]. We ontvangen het volgende antwoord van de browser:

Image

Dit is de oorspronkelijke pagina, maar we zien dat de waarde URL in het veld [Adresse] van de browser is gewijzigd. Deze is nu als volgt:

http://localhost/aspnet/chap1/params.aspx?R1=Ja&C1=één&C2=twee&txtSaisie=webprogrammering&txtMdp=ditisgeheim&areaSaisie=de+basisprincipes+van+de%0D%0Awebprogrammering&cmbValeurs=keuze3&lst1=lijst3&lst2=lijst1&lst2=lijst3&cmdRenvoyer=Verzenden&secret=uneValeur

We zien dat de keuzes die in het formulier zijn gemaakt, terug te vinden zijn in de URL. Laten we eens kijken naar de inhoud van het bestand [request.txt], waarin het verzoek van de klant is opgeslagen:

GET /aspnet/chap1/params.aspx?R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecret&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&cmdRenvoyer=Envoyer&secret=uneValeur HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
Referer: http://localhost/aspnet/chap1/params.aspx
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113

We zien een verzoek HTTP dat sterk lijkt op het verzoek dat de browser aanvankelijk had gedaan toen hij het document opvroeg zonder parameters door te geven. Er zijn twee verschillen:

GET URL HTTP/1.1
De formulierparameters zijn achter de URL van het document toegevoegd in de vorm ?param1=val1&param2=val2&...
Referer
De client geeft met deze header HTTP de URL van het document aan dat hij weergeeft op het moment dat hij de aanvraag deed

Laten we eens nader bekijken hoe de parameters zijn doorgegeven in het commando GET URL?param1=waarde1&param2=waarde2&... HTTP/1.1, waarbij de parami de namen zijn van de besturingselementen van het webformulier en ‘waarde’ de waarden die eraan zijn gekoppeld. Hieronder presenteren we een tabel met drie kolommen:

  • kolom 1: bevat de definitie van een besturingselement HTML uit het voorbeeld
  • kolom 2: toont hoe dit besturingselement in een browser wordt weergegeven
  • kolom 3: toont de waarde die door de browser naar de server wordt verzonden voor het besturingselement uit kolom 1, in de vorm zoals deze voorkomt in het verzoek GET uit het voorbeeld
besturingselement HTML
weergave
teruggestuurde waarde(n)
<input type="radio" value="Ja" name="R1">Ja
<input type="radio" name="R1" value="nee" checked>Nee
R1=Ja
- de waarde van het attribuut value van de door de gebruiker aangevinkte keuzeknop.
<input type="checkbox" name="C1" value="één">1
<input type="checkbox" name="C2" value="twee" checked>2
<input type="checkbox" name="C3" value="drie">3
C1=één
C2=twee
- waarden van de attributen value van de door de gebruiker aangevinkte selectievakjes
<input type="text" name="txtSaisie" size="20" value="enkele woorden">
txtSaisie=webprogrammering
- tekst die door de gebruiker in het invoerveld is getypt. Spaties zijn vervangen door het teken +
<input type="password" name="txtMdp" size="20" value="unMotDePasse">
txtMdp=ditisgeheim
- tekst die door de gebruiker in het invoerveld is getypt
<textarea rows="2" name="areaSaisie" cols="20">
regel1
regel2
regel3
</textarea>
areaInvoer=de+basisprincipes+van+de%0D%0A
webprogrammering+
- tekst die door de gebruiker in het invoerveld is getypt. %OD%OA is het teken voor het einde van de regel. De spaties zijn vervangen door het teken +
<select size="1" name="cmbValeurs">
<option>keuze1</option>
<option selected>keuze2</option>
<option>keuze3</option>
</select>
cmbWaarden=keuze3
- door de gebruiker gekozen waarde uit de lijst met één selectie
<select size="3" name="lst1">
<option selected>lijst1</option>
<option>lijst2</option>
<option>lijst3</option>
<option>lijst4</option>
<option>lijst5</option>
</select>
lst1=lijst3
- door de gebruiker gekozen waarde uit de lijst met één selectie
<select size="3" name="lst2" multiple>
<option selected>lijst1</option>
<option>lijst2</option>
<option selected>lijst3</option>
<option>lijst4</option>
<option>lijst5</option>
</select>
lst2=lijst1
lst2=lijst3
- door de gebruiker geselecteerde waarden uit de lijst met meerdere selectiemogelijkheden
<input type="submit" value="Verzenden" name="cmdRenvoyer">
 
cmdVerzenden=Verzenden
- naam en attribuut value van de knop waarmee de gegevens van het formulier naar de server zijn verzonden
<input type="hidden" name="secret" value="uneValeur">
 
secret=eenWaarde
- attribuut value van het verborgen veld

Je kunt je afvragen wat de server heeft gedaan met de parameters die we hem hebben doorgegeven. Eigenlijk niets. Bij ontvangst van het commando

GET /aspnet/chap1/params.aspx?R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecret&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&cmdRenvoyer=Envoyer&secret=uneValeur HTTP/1.1

heeft de webserver de parameters doorgegeven aan URL naar het document http://localhost/aspnet/chap1/params.aspx, en aan c.a.d naar het document dat we aanvankelijk hadden opgebouwd. We hebben geen code geschreven om de parameters die de client ons stuurt op te halen en te verwerken. Het lijkt dus alsof het verzoek van de client simpelweg luidt:

GET /aspnet/chap1/params.aspx

Om deze reden hebben we, als reactie op onze knop [Envoyer], dezelfde pagina ontvangen als die we aanvankelijk kregen bij het opvragen van URL en [http://localhost/aspnet/chap1/params.aspx] zonder parameters.

2.7.2.2. Methode POST

Het document HTML is nu zo geprogrammeerd dat de browser de methode POST gebruikt om de formulierwaarden naar de webserver te verzenden:

    <form method="POST" >

We vragen het nieuwe document op via de methode URL [http://localhost/aspnet/chap1/params.aspx], vullen het formulier in zoals bij de methode GET en verzenden de parameters naar de server met de knop [Envoyer]. We ontvangen de volgende responspagina van de server:

Image

We krijgen dus hetzelfde resultaat als bij de methode GET, c.a.d: de startpagina. Er is één verschil op te merken: in het veld [Adresse] van de browser verschijnen de doorgegeven parameters niet. Laten we nu eens kijken naar het verzoek dat door de client is verzonden en dat is opgeslagen in het bestand [request.txt]:

POST /aspnet/chap1/params.aspx HTTP/1.1
Connection: keep-alive
Keep-Alive: 300
Content-Length: 210
Content-Type: application/x-www-form-urlencoded
Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip,deflate
Accept-Language: en-us,en;q=0.5
Host: localhost
Referer: http://localhost/aspnet/chap1/params.aspx
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113

R1=Oui&C1=un&C2=deux&txtSaisie=programmation+web&txtMdp=ceciestsecrey&areaSaisie=les+bases+de+la%0D%0Aprogrammation+web&cmbValeurs=choix3&lst1=liste3&lst2=liste1&lst2=liste3&cmdRenvoyer=Envoyer&secret=uneValeur

Er verschijnen nieuwe gegevens in de query HTTP van de klant:

POST URL HTTP/1.1
de query GET is vervangen door een query POST. De parameters staan niet meer in de eerste regel van de query. We zien dat ze nu na een lege regel achter de query HTTP staan. Hun codering is identiek aan die in de query GET.
Content-Length
aantal „verzonden” tekens, c.a.d. Het aantal tekens dat de webserver moet lezen na ontvangst van de headers HTTP om het document op te halen dat de client naar hem verstuurt. Het document in kwestie is hier de lijst met waarden van het formulier.
Content-type
geeft het type document aan dat de client na de headers HTTP zal verzenden. Het type [application/x-www-form-urlencoded] geeft aan dat het een document is dat formulierwaarden bevat.

Er zijn twee methoden om gegevens naar een webserver te verzenden: GET en POST. Is de ene methode beter dan de andere? We hebben gezien dat als de waarden van een formulier door de browser werden verzonden met de methode GET, de browser in het veld Adresse de gevraagde parameter URL weergeeft in de vorm URL?param1=val1&param2=val2&.... Dit kan als een voordeel of als een nadeel worden gezien:

  • een voordeel als men de gebruiker de mogelijkheid wil bieden om deze geconfigureerde URL in zijn favoriete links op te nemen
  • een nadeel als men niet wil dat de gebruiker toegang heeft tot bepaalde informatie in het formulier, zoals bijvoorbeeld verborgen velden

Vanaf nu zullen we in onze formulieren vrijwel uitsluitend de methode POST gebruiken.

2.8. Conclusion

In dit hoofdstuk zijn verschillende basisconcepten van webontwikkeling behandeld:

  • de verschillende beschikbare tools en technologieën (Java, ASP, asp.net, PHP, Perl, VBScript, JavaScript)
  • de communicatie tussen client en server via het HTTP-protocol
  • het ontwerpen van een document met behulp van de taal HTML
  • het ontwerpen van invoerformulieren

Aan de hand van een voorbeeld hebben we gezien hoe een client informatie naar de webserver kan verzenden. We hebben niet laten zien hoe de server

  • deze informatie kan ophalen
  • deze verwerken
  • de klant een dynamisch antwoord sturen dat afhankelijk is van het resultaat van de verwerking

Dit valt onder het domein van webprogrammering, een onderwerp dat we in het volgende hoofdstuk behandelen met een inleiding tot de technologie ASP.NET.