Skip to content

2. Noções básicas

Neste capítulo, apresentamos os conceitos básicos da programação Web. O seu objetivo principal é dar a conhecer os princípios fundamentais da programação Web antes de os pôr em prática com uma linguagem e um ambiente específicos. Apresenta inúmeros exemplos que se recomenda testar, a fim de «assimilar» gradualmente a filosofia do desenvolvimento Web.

2.1. Os componentes de uma aplicação Web

Image

Número
Função
Exemplos comuns
1
OS Servidor
Linux, Windows
2
Servidor Web
Apache (Linux, Windows)
IIS (NT), PWS (Win9x)
3
Scripts executados no lado do servidor. Podem ser executados por módulos
do servidor ou por programas externos ao servidor (CGI).
PERL (Apache, IIS, PWS)
VBSCRIPT (IIS, PWS)
JAVASCRIPT (IIS, PWS)
PHP (Apache, IIS, PWS)
JAVA (Apache, IIS, PWS)
C#, VB.NET (IIS)
4
Base de dados — Esta pode estar na mesma máquina que
o programa que a utiliza ou noutro computador através da Internet.
Oracle (Linux, Windows)
MySQL (Linux, Windows)
Access (Windows)
SQL Server (Windows)
5
OS Cliente
Linux, Windows
6
Navegador da Web
Netscape, Internet Explorer
7
Scripts executados no lado do cliente, no navegador.
Estes scripts não têm qualquer acesso aos discos do computador do utilizador.
VBscript (IE)
JavaScript (IE, Netscape)
PerlScript (IE)
Applets JAVA

2.2. A troca de dados numa aplicação web com formulário

Image

Máquina do cliente Máquina do servidor

Número
Função
1
O navegador solicita um URL pela primeira vez (http://machine/url). Não foi passado nenhum parâmetro.
2
O servidor Web envia-lhe a página Web correspondente a este URL. Esta pode ser estática ou gerada dinamicamente por um script de servidor (SA) que pode ter utilizado o conteúdo de bases de dados (SB, SC). Neste caso, o script detetará que o URL foi solicitado sem a passagem de parâmetros e irá gerar a página inicial WEB.
O navegador recebe a página e exibe-a (CA). Os scripts do lado do navegador (CB) podem ter alterado a página inicial enviada pelo servidor. Posteriormente, através de interações entre o utilizador (CD) e os scripts (CB), a página Web será alterada. Em particular, os formulários serão preenchidos.
3
O utilizador valida os dados do formulário, que devem então ser enviados para o servidor web. O navegador volta a solicitar o URL inicial ou outro, consoante o caso, e transmite simultaneamente ao servidor os valores do formulário. Para tal, pode utilizar dois métodos denominados GET e POST. Ao receber o pedido do cliente, o servidor executa o script (SA) associado ao URL solicitado, script esse que irá detetar os parâmetros e processá-los.
4
O servidor fornece a página WEB criada pelo programa (SA, SB, SC). Esta etapa é idêntica à etapa 2 anterior. As trocas de dados realizam-se agora de acordo com as etapas 2 e 3.

2.3. Alguns recursos

Abaixo encontra-se uma lista de recursos que permitem instalar e utilizar algumas ferramentas para o desenvolvimento web. Em anexo, encontra-se um guia de instalação dessas ferramentas.

Serveur Apache
http://www.apache.org
- Apache, Instalação e Implementação, O'Reilly
Serveur IIS, PWS
http://www.microsoft.com
PERL
http://www.activestate.com
- Programação em Perl, Larry Wall, O'Reilly
- Aplicações CGI em Perl, Neuss e Vromans, O'Reilly
- a documentação HTML fornecida com o Active Perl
PHP
http://www.php.net
- Programação Web com PHP, Lacroix, Eyrolles
- Manual de utilização do PHP, disponível no site do PHP
VBSCRIPT, ASP
http://msdn.microsoft.com/scripting/vbscript/download/vbsdoc.exe
http://msdn.microsoft.com/scripting/default.htm?/scripting/vbscript
- Interface entre o WEB e a base de dados no WinNT, Alex Homer, Eyrolles
JAVASCRIPT
http://msdn.microsoft.com/scripting/jscript/download/jsdoc.exe
http://developer.netscape.com/docs/manuals/index.html
HTML
http://developer.netscape.com/docs/manuals/index.html
JAVA
http://www.sun.com
- JAVA Servlets, Jason Hunter, O'Reilly
- Programação de redes com Java, Elliotte Rusty Harold, O'Reilly
- JDBC e Java, George Reese, O'Reilly
Base de données
http://www.mysql.com
http://www.oracle.com
- O manual do MySQL está disponível no site do MySQL
- Oracle 8i no Linux, Gilles Briard, Eyrolles
- Oracle 8i no NT, Gilles Briard, Eyrolles

2.4. Notações

Daqui em diante, partiremos do princípio de que foram instaladas algumas ferramentas e adotaremos as seguintes notações:

notação
significado
<apache>
raiz da árvore de diretórios do servidor Apache
<apache-DocumentRoot>
raiz das páginas Web servidas pelo Apache. É nesta raiz que as páginas Web devem estar localizadas. Assim, o URL http://localhost/page1.htm corresponde ao ficheiro <apache-DocumentRoot>\page1.htm.
<apache-cgi-bin>
raiz da árvore de diretórios associada ao alias cgi-bin e onde é possível colocar scripts CGI para o Apache. Assim, o URL http://localhost/cgi-bin/test1.pl corresponde ao ficheiro <apache-cgi-bin>\test1.pl.
<pws-DocumentRoot>
raiz das páginas Web geradas pelo PWS. É nesta raiz que as páginas Web devem estar localizadas. Assim, o URL http://localhost/page1.htm corresponde ao ficheiro <pws-DocumentRoot>\page1.htm.
<perl>
raiz da árvore de diretórios do linguagem Perl. O executável perl.exe encontra-se geralmente em <perl>\bin.
<php>
raiz da árvore da linguagem PHP. O executável php.exe encontra-se geralmente em <php>.
<java>
raiz da árvore de diretórios do Java. Os executáveis relacionados com o Java encontram-se em <java>\bin.
<tomcat>
raiz do servidor Tomcat. Encontram-se exemplos de servlets em <tomcat>\webapps\examples\servlets e exemplos de páginas em JSP, em <tomcat>\webbapps\examples\jsp

Para cada uma destas ferramentas, consulte o anexo, que fornece orientações para a sua instalação.

2.5. Páginas Web estáticas, Páginas Web dinâmicas

Uma página estática é representada por um ficheiro HTML. Uma página dinâmica, por sua vez, é gerada «em tempo real» pelo servidor Web. Neste parágrafo, propomos vários testes com diferentes servidores Web e diferentes linguagens de programação, a fim de demonstrar a universalidade do conceito Web.

2.5.1. Página estática HTML (Linguagem de Marcação HyperText)

Consideremos o seguinte código HTML:

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

que gera a seguinte página web:

Os testes

Image

  • iniciar o servidor Apache

  • colocar o script essai1.html em <apache-DocumentRoot>

  • visualizar o URL http://localhost/essai1.html num navegador

  • encerrar o servidor Apache

  • iniciar o servidor PWS

  • colocar o script essai1.html no <pws-DocumentRoot>

  • visualizar o URL http://localhost/essai1.html com um navegador

2.5.2. Uma página ASP (Active Server Pages)

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

gera a seguinte página web:

Image

O teste

  • iniciar o servidor PWS

  • inserir o script essai2.asp no <pws-DocumentRoot>

  • aceder à página URL http://localhost/essai2.asp com um navegador

2.5.3. Um script PERL (Practical Extracting and Reporting Language)

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

A primeira linha é o caminho do executável perl.exe. Deve ser adaptado, se necessário. Uma vez executado por um servidor Web, o script gera a seguinte página:

Image

O teste

  • servidor Web: Apache

  • para informação, consulte o ficheiro de configuração srm.conf ou httpd.conf, consoante a versão do Apache, em <apache>\confs e procure a linha que refere o cgi-bin para saber qual é o diretório <apache-cgi-bin> onde deve colocar o essai3.pl.

  • coloque o script essai3.pl no <apache-cgi-bin>

  • aceda ao URL http://localhost/cgi-bin/essai3.pl

Note-se que demora mais tempo a carregar a página perl do que a página asp. Isto deve-se ao facto de o script Perl ser executado por um interpretador Perl que tem de ser carregado antes de poder executar o script. Este não permanece permanentemente na memória.

2.5.4. Um script PHP (Página Pessoal)

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

O script anterior gera a seguinte página web:

Os testes

Image

Image

  • consultar o ficheiro de configuração srm.conf ou httpd.conf do Apache em <Apache>\confs

  • a título informativo, verificar as linhas de configuração de php

  • iniciar o servidor Apache

  • colocar o essai4.php no <apache-DocumentRoot>

  • solicitar o URL http://localhost/essai4.php

  • iniciar o servidor PWS

  • a título informativo, verificar a configuração do PWS no que diz respeito ao PHP

  • inserir o essai4.php no <pws-DocumentRoot>\php

  • solicitar o URL http://localhost/essai4.php

2.5.5. Um script JSP (Java Server Pages)

O script heure.jsp

<%  //programa Java que apresenta a hora %>

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

<% 
     // código JAVA para calcular a hora
  Calendar calendrier=Calendar.getInstance();
  int heures=calendrier.get(Calendar.HOUR_OF_DAY);
  int minutes=calendrier.get(Calendar.MINUTE);
  int secondes=calendrier.get(Calendar.SECOND);
   // horas, minutos e segundos são variáveis globais
   // que poderão ser utilizadas no código HTML
%>

<% // código 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>

Depois de executado pelo servidor web, este script gera a seguinte página:

Image

Os testes

  • colocar o script heure.jsp em <tomcat>\jakarta-tomcat\webapps\examples\jsp (Tomcat 3.x) ou em <tomcat>\webapps\examples\jsp (Tomcat 4.x)
  • Inicie o servidor Tomcat
  • aceder ao URL em http://localhost:8080/examples/jsp/heure.jsp

2.5.6. Conclusão

Os exemplos anteriores demonstraram que:

  • uma página HTML pode ser gerada dinamicamente por um programa. É esse o sentido da programação Web.
  • que as linguagens e os servidores Web utilizados podem ser diversos. Atualmente, observam-se as seguintes grandes tendências:
    • as combinações Apache/PHP (Windows, Linux) e IIS/PHP (Windows)
    • a tecnologia ASP.NET nas plataformas Windows, que associam o servidor IIS a uma linguagem .NET (C#, VB.NET, ...)
    • a tecnologia de servlets Java e páginas JSP que funcionam com diferentes servidores (Tomcat, Apache, IIS) e em diferentes plataformas (Windows, Linux). É esta última tecnologia que será abordada mais detalhadamente neste documento.

2.6. Scripts do lado do navegador

Uma página HTML pode conter scripts que serão executados pelo navegador. Existem inúmeras linguagens de script do lado do navegador. Aqui estão algumas delas:

Linguagem
Navegadores compatíveis
VBScript
IE
JavaScript
IE, Netscape
PerlScript
IE
Java
IE, Netscape

Vejamos alguns exemplos.

2.6.1. Uma página Web com um script VBScript, do lado do navegador

A página 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>

A página HTML acima não contém apenas o código HTML, mas também um programa destinado a ser executado pelo navegador que carregar esta página. O código é o seguinte:

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

As balizas <script></script> servem para delimitar os scripts na página HTML. Estes scripts podem ser escritos em diferentes linguagens e é a opção language da baliza <script> que indica a linguagem utilizada. Neste caso, é VBScript. Não iremos aprofundar esta linguagem. O script acima define uma função chamada réagir que exibe uma mensagem. Quando é que esta função é chamada? É a seguinte linha de código HTML que nos indica isso:

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

O atributo onclick indica o nome da função a ser chamada quando o utilizador clicar no botão OK. Quando o navegador tiver carregado esta página e o utilizador clicar no botão OK, obter-se-á a seguinte página:

Image

Os testes

Apenas o navegador IE é capaz de executar scripts VBScript. O Netscape necessita de complementos de software para o fazer. Poderão ser realizados os seguintes testes:

  • servidor Apache

  • script vbs1.html no <apache-DocumentRoot>

  • aceder à URL http://localhost/vbs1.html com o navegador IE

  • servidor PWS

  • script vbs1.html no <pws-DocumentRoot>

  • aceder à URL http://localhost/vbs1.html com o navegador IE

2.6.2. Uma página Web com um script JavaScript, no lado do navegador

A página: 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>

Temos aqui algo idêntico à página anterior, com a diferença de que substituímos a linguagem VBScript pela linguagem JavaScript. Esta tem a vantagem de ser aceite pelos dois navegadores, o IE e o Netscape. A sua execução produz os mesmos resultados:

Image

Os testes

  • servidor Apache

  • script js1.html no <apache-DocumentRoot>

  • aceder à URL http://localhost/js1.html com o navegador IE ou Netscape

  • servidor PWS

  • script js1.html no <pws-DocumentRoot>

  • aceder à URL http://localhost/js1.html com o navegador IE ou Netscape

2.7. As interações cliente-servidor

Voltemos ao nosso esquema inicial, que ilustrava os intervenientes de uma aplicação web:

Aqui, estamos interessados nas trocas entre o computador cliente e o computador servidor. Estas ocorrem através de uma rede e é importante recordar a estrutura geral das trocas entre dois computadores remotos.

2.7.1. O modelo OSI

O modelo de rede aberta denominado OSI (Modelo de Referência para a Interligação de Sistemas Abertos), definido pela ISO (Organização Internacional de Normalização), descreve uma rede ideal em que a comunicação entre máquinas pode ser representada por um modelo de sete camadas:

Cada camada recebe serviços da camada inferior e fornece os seus à camada superior. Suponhamos que duas aplicações localizadas em máquinas A e B diferentes pretendem comunicar: fazem-no ao nível da camada Application. Não precisam de conhecer todos os detalhes do funcionamento da rede: cada aplicação entrega a informação que pretende transmitir à camada inferior: a camada Présentation. A aplicação só precisa, portanto, de conhecer as regras de interface com a camada Présentation. Assim que a informação chega à camada Présentation, é encaminhada, de acordo com outras regras, para a camada Session e assim sucessivamente, até que a informação chegue ao suporte físico e seja transmitida fisicamente para a máquina de destino. Aí, será submetida ao processo inverso ao que sofreu na máquina remetente.

Em cada camada, o processo remetente encarregado de enviar a informação transmite-a a um processo recetor na outra máquina, pertencente à mesma camada que ele. Faz-o de acordo com determinadas regras a que se chama protocolo da camada. Temos, portanto, o seguinte esquema de comunicação final:

A função das diferentes camadas é a seguinte:

Physique
Assegura a transmissão de bits num suporte físico. Nesta camada encontram-se equipamentos terminais de processamento de dados (E.T.T.D.), tais como terminais ou computadores, bem como equipamentos de terminação de circuitos de dados (E.T.C.D.), tais como moduladores/demoduladores, multiplexadores e concentradores. Os pontos de interesse a este nível são:
. a escolha da codificação da informação (analógica ou digital)
. a escolha do modo de transmissão (síncrono ou assíncrono).
Liaison de données
Oculta as características físicas da camada Física. Deteta e corrige os erros de transmissão.
Réseau
Gere o percurso que as informações enviadas pela rede devem seguir. A isto chama-se routage: determinar o percurso que uma informação deve seguir para chegar ao seu destinatário.
Transport
Permite a comunicação entre duas aplicações, enquanto as camadas anteriores apenas permitiam a comunicação entre máquinas. Um serviço prestado por esta camada pode ser o multiplexamento: a camada de transporte poderá utilizar uma mesma ligação de rede (de máquina para máquina) para transmitir informações pertencentes a várias aplicações.
Session
Nesta camada, encontramos serviços que permitem a uma aplicação abrir e manter uma sessão de trabalho numa máquina remota.
Présentation
O seu objetivo é uniformizar a representação dos dados nas diferentes máquinas. Assim, os dados provenientes de uma máquina A serão «formatados» pela camada Présentation da máquina A, de acordo com um formato padrão, antes de serem enviados pela rede. Ao chegarem à camada Présentation da máquina destinatária B, que as reconhecerá graças ao seu formato padrão, serão formatadas de outra forma para que a aplicação da máquina B as reconheça.
Application
Nesta fase, encontram-se as aplicações geralmente mais próximas do utilizador, tais como o correio eletrónico ou a transferência de ficheiros.

2.7.2. O modelo TCP/IP

O modelo OSI é um modelo ideal. O conjunto de protocolos TCP/IP aproxima-se dele da seguinte forma:

  • a interface de rede (a placa de rede do computador) assegura as funções das camadas 1 e 2 do modelo OSI
  • a camada IP (Protocolo de Internet) assegura as funções da camada 3 (rede)
  • a camada TCP (Protocolo de Controlo de Transferência) ou UDP (Protocolo de Datagrama do Utilizador) desempenha as funções da camada 4 (transporte). O protocolo TCP garante que os pacotes de dados trocados entre os computadores cheguem corretamente ao destino. Caso contrário, reenvia os pacotes que se perderam. O protocolo UDP não desempenha essa função, cabendo ao programador de aplicações fazê-lo. É por isso que, na Internet — que não é uma rede 100% fiável —, o protocolo TCP é o mais utilizado. Fala-se, então, de rede TCP-IP.
  • A camada de Aplicação abrange as funções dos níveis 5 a 7 do modelo OSI.

As aplicações web encontram-se na camada Application e, por conseguinte, baseiam-se nos protocolos TCP-IP. As camadas Application das máquinas cliente e servidor trocam mensagens que são confiadas às camadas 1 a 4 do modelo para serem encaminhadas para o destino. Para se compreenderem, as camadas de aplicação de ambas as máquinas têm de «falar» a mesma linguagem ou protocolo. O protocolo das aplicações Web chama-se HTTP (HyperText Transfer Protocol). Trata-se de um protocolo de tipo texto, c.a.d, em que as máquinas trocam linhas de texto na rede para se compreenderem. Essas trocas são padronizadas, c.a.d, de modo que o cliente dispõe de um determinado conjunto de mensagens para indicar exatamente o que pretende ao servidor e este, por sua vez, dispõe igualmente de um determinado conjunto de mensagens para dar a sua resposta ao cliente. Esta troca de mensagens tem a seguinte forma:

Cliente --> Servidor

Quando o cliente faz o seu pedido ao servidor web, envia

  1. linhas de texto no formato HTTP para indicar o que pretende
  2. uma linha em branco
  3. opcionalmente, um documento

Servidor --> Cliente

Quando o servidor responde ao cliente, envia

  1. linhas de texto no formato HTTP para indicar o que está a enviar
  2. uma linha vazia
  3. opcionalmente, um documento

As trocas têm, portanto, o mesmo formato em ambos os sentidos. Em ambos os casos, pode haver o envio de um documento, embora seja raro um cliente enviar um documento ao servidor. Mas o protocolo HTTP prevê essa possibilidade. É isso que permite, por exemplo, que os assinantes de um fornecedor de acesso descarreguem diversos documentos para o seu site pessoal alojado nesse fornecedor de acesso. Os documentos trocados podem ser quaisquer. Tomemos como exemplo um navegador que solicita uma página web contendo imagens:

  1. o navegador liga-se ao servidor web e solicita a página que pretende. Os recursos solicitados são identificados de forma única por meio de URL (Uniform Resource Locator). O navegador envia apenas cabeçalhos HTTP e nenhum documento.
  2. O servidor responde-lhe. Em primeiro lugar, envia cabeçalhos HTTP indicando o tipo de resposta que está a enviar. Pode tratar-se de um erro se a página solicitada não existir. Se a página existir, o servidor indicará nos cabeçalhos HTTP da sua resposta que, após estes, irá enviar um documento HTML (HyperText Markup Language). Este documento é uma sequência de linhas de texto no formato HTML. Um texto HTML contém balizas (marcadores) que fornecem ao navegador instruções sobre a forma de apresentar o texto.
  3. O cliente sabe, com base nos cabeçalhos HTTP do servidor, que irá receber um documento HTML. Irá analisar esse documento e poderá perceber que este contém referências a imagens. Estas imagens não se encontram no documento HTML. Por isso, faz um novo pedido ao mesmo servidor web para solicitar a primeira imagem de que necessita. Este pedido é idêntico ao feito no ponto 1, exceto que o recurso solicitado é diferente. O servidor irá processar esta solicitação, enviando ao seu cliente a imagem solicitada. Desta vez, na sua resposta, os cabeçalhos HTTP especificarão que o documento enviado é uma imagem e não um documento HTML.
  4. O cliente recebe a imagem enviada. Os passos 3 e 4 serão repetidos até que o cliente (geralmente um navegador) tenha todos os documentos necessários para apresentar a página na íntegra.

2.7.3. O protocolo HTTP

Vamos explorar o protocolo HTTP através de exemplos. O que é que um navegador e um servidor web trocam entre si?

2.7.3.1. A resposta de um servidor HTTP

Vamos descobrir aqui como um servidor web responde aos pedidos dos seus clientes. O serviço Web ou serviço HTTP é um serviço TCP-IP que funciona habitualmente na porta 80. Pode funcionar noutra porta. Nesse caso, o navegador do cliente teria de especificar essa porta no URL que solicita. Um URL tem o seguinte formato geral:

protocolo://máquina[:port]/caminho/informações

onde

protocolo
http para o serviço web. Um navegador também pode funcionar como cliente de serviços ftp, news, telnet, etc.
máquina
nome da máquina onde o serviço web está a funcionar
porta
porta do serviço web. Se for 80, pode omitir-se o número da porta. Este é o caso mais frequente
caminho
caminho que indica o recurso solicitado
informações
informações adicionais fornecidas ao servidor para especificar o pedido do cliente

O que faz um navegador quando um utilizador solicita o carregamento de um URL?

  1. abre uma comunicação TCP-IP com a máquina e a porta indicadas na parte «machine[:port]» do URL. Estabelecer uma comunicação TCP-IP significa criar um «canal» de comunicação entre duas máquinas. Uma vez criado esse canal, todas as informações trocadas entre as duas máquinas passarão por ele. A criação deste canal TCP-IP ainda não envolve o protocolo Web HTTP.
  2. Com o canal TCP-IP criado, o cliente irá enviar o seu pedido ao servidor Web, enviando-lhe linhas de texto (comandos) no formato HTTP. Enviará ao servidor a parte «caminho/informações» do URL
  3. o servidor responderá da mesma forma e no mesmo canal
  4. um dos dois parceiros tomará a decisão de encerrar o canal. Isso depende do protocolo HTTP utilizado. Com o protocolo HTTP 1.0, o servidor encerra a ligação após cada uma das suas respostas. Isto obriga um cliente que precise de efetuar várias solicitações para obter os diferentes documentos que constituem uma página web a abrir uma nova ligação em cada solicitação, o que acarreta um custo. Com o protocolo HTTP/1.1, o cliente pode indicar ao servidor para manter a ligação aberta até que lhe peça para a encerrar. Assim, pode recuperar todos os documentos de uma página web com uma única ligação e encerrar ele próprio a ligação assim que o último documento for obtido. O servidor detetará este encerramento e também encerrará a ligação.

Para explorar as trocas de dados entre um cliente e um servidor web, vamos utilizar um cliente TCP genérico. Trata-se de um programa que pode atuar como cliente de qualquer serviço que utilize um protocolo de comunicação baseado em linhas de texto, como é o caso do protocolo HTTP. Estas linhas de texto serão digitadas pelo utilizador através do teclado. Para tal, é necessário que conheça o protocolo de comunicação do serviço ao qual pretende aceder. A resposta do servidor é, em seguida, apresentada no ecrã. O programa foi escrito em Java e encontra-se no anexo. Utilizamo-lo aqui numa janela do DOS no Windows e chamamo-lo da seguinte forma:

java clientTCPgenerique máquina porta

com

machine
nome da máquina onde o serviço a contactar está a funcionar
port
porta onde o serviço é prestado

Com estas duas informações, o programa irá estabelecer uma ligação TCP-IP com a máquina e a porta indicadas. Esta ligação servirá para a troca de linhas de texto entre o cliente e o servidor web. As linhas do cliente são digitadas pelo utilizador no teclado e enviadas para o servidor. As linhas de texto devolvidas pelo servidor como resposta são apresentadas no ecrã. Assim, pode estabelecer-se um diálogo diretamente entre o utilizador ao teclado e o servidor web. Vamos experimentar com os exemplos já apresentados. Tínhamos criado a seguinte página estática HTML:

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

que visualizamos num navegador:

Image

Vemos que o URL solicitado é: http://localhost:81/essais/essai1.html. O servidor do serviço web é, portanto, localhost (=servidor local) e a porta 81. Se solicitarmos a visualização do texto HTML desta página web (Exibir/Fonte), encontramos o texto HTML inicialmente criado:

Image

Agora, vamos utilizar o nosso cliente genérico TCP para solicitar o mesmo 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>

Ao iniciar o cliente através do comando java clientTCPgenerique localhost 81, foi criado um canal entre o programa e o servidor web a funcionar na mesma máquina (localhost) e na porta 81. As trocas cliente-servidor no formato HTTP podem começar. Recorde-se que estas têm três componentes:

  1. cabeçalhos HTTP
  2. linha em branco
  3. dados opcionais

No nosso exemplo, o cliente envia apenas um pedido:

GET /testes/essai1.html HTTP/1.0

Esta linha tem três componentes:

GET
comando HTTP para solicitar um recurso. Existem outros:
HEAD solicita um recurso, mas limitando-se aos cabeçalhos HTTP da resposta do servidor. O próprio recurso não é enviado.
PUT permite ao cliente enviar um documento para o servidor
/essais/essai1.html
recurso solicitado
HTTP/1.0
Nível do protocolo HTTP utilizado. Neste caso, 1.0. Isto significa que o servidor encerrará a ligação assim que tiver enviado a sua resposta

Os cabeçalhos HTTP devem ser sempre seguidos por uma linha em branco. Foi isso que o cliente fez aqui. É assim que o cliente ou o servidor sabe que a parte HTTP da troca de dados está concluída. Neste caso, para o cliente, o processo está concluído. Não tem nenhum documento para enviar. Começa então a resposta do servidor, composta, no nosso exemplo, por todas as linhas que começam com o símbolo <--. Envia primeiro uma série de cabeçalhos HTTP, seguidos de uma linha em branco:

<-- 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
o servidor indica
  • que compreende o protocolo HTTP versão 1.1
  • que dispõe do recurso solicitado (código 200, mensagem OK)
Date: ...
a data/hora da resposta
Server: 
o servidor identifica-se. Neste caso, trata-se de um servidor Apache
Last-Modified:
data da última modificação do recurso solicitado pelo cliente
ETag:
...
Accept-Ranges: bytes
unidade de medida dos dados enviados. Neste caso, o byte
Content-Length: 161
número de bytes do documento que será enviado após os cabeçalhos HTTP. Este número corresponde, na verdade, ao tamanho em bytes do ficheiro essai1.html:
E:\data\serge\web\essais>dir essai1.html

08/07/2002  10:00                  161 essai1.html
Connection: close
O servidor indica que irá encerrar a ligação assim que o documento for enviado
Content-type: text/html
o servidor indica que vai enviar texto (text) no formato HTML (html).

O cliente recebe estes cabeçalhos HTTP e sabe agora que vai receber 161 octetos que representam um documento HTML. O servidor envia estes 161 octetos imediatamente a seguir à linha vazia que assinalava o fim dos cabeçalhos HTTP:

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

Reconhecemos aqui o ficheiro HTML criado inicialmente. Se o nosso cliente fosse um navegador, após receber estas linhas de texto, interpretá-las-ia para apresentar ao utilizador, através do teclado, a seguinte página:

Image

Vamos utilizar novamente o nosso cliente genérico TCP para solicitar o mesmo recurso, mas desta vez com o comando HEAD, que solicita apenas os cabeçalhos da resposta:


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

Obtenemos o mesmo resultado que anteriormente, sem o documento HTML. Note-se que, no seu pedido HEAD, o cliente indicou que estava a utilizar o protocolo HTTP, versão 1.1. Isto obriga-o a enviar um segundo cabeçalho HTTP, especificando o par machine:port que o cliente pretende consultar: Host: localhost:81.

Agora, vamos solicitar uma imagem tanto com um navegador como com o cliente genérico TCP. Primeiro, com um navegador:

Image

O ficheiro univ01.gif tem 3167 octetos:

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

Vamos agora utilizar o cliente genérico 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
<--

Deve-se ter em conta os seguintes pontos na resposta do servidor:

HEAD
  • só solicitamos os cabeçalhos HTTP do recurso. Com efeito, uma imagem é um ficheiro binário e não um ficheiro de texto, e a sua exibição no ecrã como texto não resulta em nada legível.
Content-Length: 3167
  • esta é a dimensão do ficheiro univ01.gif
Content-Type: image/gif
  • o servidor indica ao seu cliente que lhe vai enviar um documento do tipo image/gif, c.a.d. uma imagem no formato GIF. Se a imagem estivesse no formato JPEG, o tipo do documento teria sido image/jpeg. Os tipos de documentos são padronizados e denominam-se tipos MIME (Multi-purpose Mail Internet Extension).

2.7.3.2. O pedido de um cliente HTTP

Agora, coloquemos a seguinte questão: se quisermos escrever um programa que «comunique» com um servidor web, que comandos deve este enviar ao servidor web para obter um determinado recurso? Nos exemplos anteriores, obtivemos um início de resposta. Encontrámos três comandos:

GET ressource protocole
  • para solicitar um determinado recurso de acordo com uma determinada versão do protocolo HTTP. O servidor envia uma resposta no formato HTTP, seguida de uma linha em branco e, em seguida, do recurso solicitado
HEAD ressource protocole
  • o mesmo, exceto que, neste caso, a resposta limita-se aos cabeçalhos HTTP e à linha vazia
host: machine:port
  • para especificar (protocolo HTTP 1.1) a máquina e a porta do servidor web consultado

Existem outros comandos. Para os descobrir, vamos agora utilizar um servidor TCP genérico. Trata-se de um programa escrito em Java, que também encontrará no anexo. É iniciado com: java serveurTCPgenerique portEcoute, em que portEcoute é a porta à qual os clientes devem ligar-se. O programa serveurTCPgenerique

  • exibe no ecrã os comandos enviados pelos clientes
  • envia-lhes, como resposta, as linhas de texto digitadas no teclado por um utilizador. É, portanto, este último que funciona como servidor. No nosso exemplo, o utilizador ao teclado desempenhará o papel de um serviço web.

Vamos agora simular um servidor web, iniciando o nosso servidor genérico na porta 88:


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

Vamos agora utilizar um navegador e aceder à página http://localhost:88/exemple.html. O navegador irá então ligar-se à porta 88 da máquina localhost e, em seguida, solicitar a página /exemple.html:

Image

Vejamos agora a janela do nosso servidor, que apresenta o que o cliente lhe enviou (algumas linhas específicas do funcionamento do programa serveurTCPgenerique foram omitidas por uma questão de simplificação):


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

As linhas precedidas pelo sinal <-- são as enviadas pelo cliente. Descobrimos assim cabeçalhos HTTP que ainda não tínhamos encontrado:

Accept:
  • lista de tipos de documentos MIME que o navegador sabe processar.
Accept-language:
  • o idioma preferencialmente aceite para os documentos.
Accept-Encoding:
  • o tipo de codificação dos documentos que o navegador consegue processar
User-Agent:
  • identidade do cliente
Connection:
  • Close: o servidor encerrará a ligação após ter fornecido a sua resposta
  • Keep-Alive: a ligação permanecerá aberta após a receção da resposta do servidor. Isto permitirá ao navegador solicitar os restantes documentos necessários à construção da página sem ter de restabelecer uma ligação.

Os cabeçalhos HTTP enviados pelo navegador terminam com uma linha em branco, tal como esperado.

Vamos elaborar uma resposta para o nosso cliente. O utilizador ao teclado é, neste caso, o verdadeiro servidor e pode elaborar uma resposta manualmente. Recordemos a resposta dada por um servidor Web num exemplo anterior:

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

Vamos tentar elaborar manualmente (no teclado) uma resposta semelhante. As linhas que começam por --> : são enviadas ao cliente:

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

O comando fin é específico do funcionamento do programa serveurTCPgenerique. Interrompe a execução do programa e encerra a ligação entre o servidor e o cliente. Limitaram-se, na nossa resposta, aos seguintes cabeçalhos HTTP:

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

Não indicamos o tamanho do ficheiro que vamos enviar (Content-Length), mas limitamo-nos a indicar que vamos encerrar a ligação (Connection: close) após o envio do mesmo. Isso é suficiente para o navegador. Ao verificar que a ligação foi encerrada, o navegador saberá que a resposta do servidor está concluída e apresentará a página HTML que lhe foi enviada. Esta página é a seguinte:

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

O navegador apresenta então a seguinte página:

Image

Se, no exemplo acima, introduzirmos View/Source para ver o que o navegador recebeu, obtemos:

Image

ou seja, exatamente o que foi enviado a partir do servidor genérico.

2.8. A linguagem HTML

Um navegador da Web pode apresentar vários documentos, sendo o mais comum o documento HTML (HyperText Markup Language). Trata-se de um texto formatado com balizas do tipo <balise>texte</balise>. Assim, o texto <B>important</B> apresentará o texto importante em negrito. Existem balizas isoladas, como a baliza <hr>, que apresenta uma linha horizontal. Não iremos analisar as balizas que podem ser encontradas num texto HTML. Existem inúmeros programas WYSIWYG que permitem criar uma página web sem escrever uma única linha de código HTML. Estas ferramentas geram automaticamente o código HTML a partir de um layout criado com o rato e controlos predefinidos. Assim, é possível inserir (com o rato) uma tabela na página e, em seguida, consultar o código HTML gerado pelo software para descobrir as balizas a utilizar para definir uma tabela numa página web. Não é mais complicado do que isso. Além disso, o conhecimento da linguagem HTML é indispensável, uma vez que as aplicações web dinâmicas têm de gerar elas próprias o código HTML a enviar aos clientes web. Este código é gerado por programa e é, naturalmente, necessário saber o que deve ser gerado para que o cliente tenha a página web que deseja.

Resumindo, não é necessário conhecer toda a linguagem HTML para começar a programar para a Web. No entanto, esse conhecimento é necessário e pode ser adquirido através da utilização de software WYSIWYG para a criação de páginas Web, como o Word, o FrontPage, o DreamWeaver e dezenas de outros. Outra forma de descobrir as subtilezas da linguagem HTML é navegar na Web e visualizar o código-fonte das páginas que apresentam características interessantes e ainda desconhecidas para si.

2.8.1. Um exemplo

Consideremos o exemplo seguinte, criado com o FrontPage Express, uma ferramenta gratuita incluída no Internet Explorer. O código gerado pelo FrontPage foi aqui simplificado. Este exemplo apresenta alguns elementos que podem ser encontrados num documento web, tais como:

  • uma tabela
  • uma imagem
  • um link

Image

Um documento HTML tem a seguinte estrutura geral:

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

Todo o documento é delimitado pelas balizas <html>...</html>. É composto por duas partes:

  1. <head>...</head>: esta é a parte não visível do documento. Fornece informações ao navegador que irá apresentar o documento. Nesta parte encontra-se frequentemente a baliza <title>...</title>, que define o texto a apresentar na barra de título do navegador. Também podem existir outras balizas, nomeadamente as que definem as palavras-chave do documento, palavras-chave posteriormente utilizadas pelos motores de busca. Nesta parte também podem encontrar-se scripts, na maioria das vezes escritos em JavaScript ou VBScript, que serão executados pelo navegador.
  2. <body atributos>...</body>: esta é a parte que será apresentada pelo navegador. As balizas HTML contidas nesta parte indicam ao navegador a forma visual «desejada» para o documento. Cada navegador interpretará estas balizas à sua maneira. Dois navegadores podem, assim, visualizar de forma diferente um mesmo documento web. Este é, geralmente, um dos desafios dos web designers.

O código HTML do nosso documento de exemplo é o seguinte:

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

No código, foram destacados apenas os pontos que nos interessam:

Elemento
etiquetas e exemplos HTML
titre du document
<title>balises</title>
balises aparecerá na barra de título do navegador que exibirá o documento
barre horizontale
<hr>: exibe uma linha horizontal
tableau
<atributos da tabela>....</table>: para definir a tabela
<tr atributos>...</tr>: para definir uma linha
<td atributos>...</td>: para definir uma célula
exemplos:
<table border="1">...</table>: o atributo border define a espessura da borda da tabela
<td valign="middle" align="center" width="150">célula(1,2)</td>: define uma célula cujo conteúdo será célula(1,2). Este conteúdo será centrado verticalmente (valign="middle") e horizontalmente (align="center"). A célula terá uma largura de 150 píxeis (width="150")
image
<img border="0" src="/images/univ01.gif" width="80" height="95">: define uma imagem sem borda (border="0"), com 95 píxeis de altura (height="95"), com 80 píxeis de largura (width="80") e cujo ficheiro de origem é /images/univ01.gif no servidor web (src="/images/univ01.gif"). Esta ligação encontra-se num documento web que foi obtido com o URL http://localhost:81/html/balises.htm. Assim, o navegador irá solicitar o URL http://localhost:81/images/univ01.gif para obter a imagem aqui referenciada.
lien
<a href="http://istia.univ-angers.fr">aqui</a>: faz com que o texto ici funcione como um link para o URL http://istia.univ-angers.fr.
fond de page
<body background="/images/standard.jpg">: indica que a imagem que deve servir de fundo da página se encontra em URL /images/standard.jpg no servidor web. No contexto do nosso exemplo, o navegador irá solicitar o URL http://localhost:81/images/standard.jpg para obter esta imagem de fundo.

Neste exemplo simples, vemos que, para construir o documento na íntegra, o navegador tem de efetuar três pedidos ao servidor:

  1. http://localhost:81/html/balises.htm para obter o código-fonte HTML do documento
  2. http://localhost:81/images/univ01.gif para obter a imagem univ01.gif
  3. http://localhost:81/images/standard.jpg para obter a imagem de fundo standard.jpg

O exemplo seguinte apresenta um formulário Web também criado com FrontPage.

Image

O código HTML gerado pelo FrontPage e ligeiramente simplificado é o seguinte:

<html>

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

A correspondência entre a verificação visual <--> a baliza HTML é a seguinte:

Controlo
etiqueta HTML
formulaire
<form method="POST" >
champ de saisie
<input type="text" name="txtSaisie" size="20" value="algumas palavras">
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">
linha1
linha 2
linha 3
</textarea>
boutons radio
<input type="radio" value="Sim" name="R1">Sim
<input type="radio" name="R1" value="não" checked>Não
cases à cocher
<input type="checkbox" name="C1" value="um">1
<input type="checkbox" name="C2" value="dois" checked>2
<input type="checkbox" name="C3" value="três">3
Combo
<select size="1" name="cmbValeurs">
<option>opção1</option>
<option selected>opção 2</option>
<option>opção 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="Enviar" name="cmdRenvoyer">
bouton de type reset
<input type="reset" value="Restaurar" name="cmdRétablir">
bouton de type button
<input type="button" value="Apagar" name="cmdEffacer" onclick="effacer()">

Vamos analisar estes diferentes controlos.

2.8.1.1. O formulário

formulaire
<form method="POST" >
balise HTML
<form name="..." method="..." action="...">...</form>
attributs
name="frmexemple": nome do formulário
method="..." : método utilizado pelo navegador para enviar ao servidor web os valores recolhidos no formulário
action="..." : URL para onde serão enviados os valores recolhidos no formulário.
Um formulário web é delimitado pelas balizas <form>...</form>. O formulário pode ter um nome (name="xx"). É o caso de todos os controlos que se podem encontrar num formulário. Este nome é útil se o documento web contiver scripts que precisem de referenciar elementos do formulário. O objetivo de um formulário é recolher as informações fornecidas pelo utilizador através do teclado/rato e enviá-las para uma URL do servidor web. Qual? Aquela referenciada no atributo action="URL". Se este atributo estiver ausente, as informações serão enviadas para o servidor do documento em que o formulário se encontra. Seria esse o caso no exemplo acima. Até agora, sempre vimos o cliente web como «solicitando» informações a um servidor web, nunca como «fornecendo» informações a este. Como é que um cliente web consegue fornecer informações (as contidas no formulário) a um servidor web? Voltaremos a este assunto em pormenor um pouco mais adiante. Pode utilizar dois métodos diferentes, denominados POST e GET. O atributo method="méthode", com o método igual a GET ou POST, da baliza <form> indica ao navegador o método a utilizar para enviar as informações recolhidas no formulário para o URL especificado pelo atributo action="URL". Quando o atributo method não é especificado, o método GET é utilizado por predefinição.

2.8.1.2. Campo de introdução

Image

Image

champ de saisie
<input type="text" name="txtSaisie" size="20" value="algumas palavras">
<input type="password" name="txtMdp" size="20" value="unMotDePasse">
balise HTML
<input type="..." name="..." size=".." value="..">
A baliza «input» existe para vários controlos. É o atributo type que permite distinguir esses diferentes controlos entre si.
attributs
type="text": especifica que se trata de um campo de introdução de dados
type="password": os caracteres presentes no campo de introdução são substituídos por asteriscos (*). Esta é a única diferença em relação ao campo de introdução normal. Este tipo de controlo é adequado para a introdução de palavras-passe.
size="20": número de caracteres visíveis no campo — não impede a introdução de mais caracteres
name="txtSaisie" : nome do controlo
value="algumas palavras": texto que será exibido no campo de entrada.

2.8.1.3. Campo de introdução de texto com várias linhas

Image

champ de saisie multilignes
<textarea rows="2" name="areaSaisie" cols="20">
ligne1
ligne2
ligne3
</textarea>
balise HTML
<textarea ...>texto</textarea>
exibe uma área de introdução de texto com várias linhas, com texto preenchido inicialmente
attributs
rows="2": número de linhas
cols="'20": número de colunas
name="areaSaisie": nome do controlo

2.8.1.4. Botões de opção

Image

boutons radio
<input type="radio" value="Sim" name="R1">Sim
<input type="radio" name="R1" value="não" checked>Não
balise HTML
<input type="radio" atributo2="valor2" ....>texto
exibe um botão de opção com texto ao lado.
attributs
name="radio": nome do controlo. Os botões de opção com o mesmo nome formam um grupo de botões mutuamente exclusivos: só é possível selecionar um deles.
value="valor": valor atribuído ao botão de opção. Não se deve confundir este valor com o texto apresentado ao lado do botão de opção. Este último destina-se apenas à visualização.
checked: se esta palavra-chave estiver presente, o botão de opção está marcado; caso contrário, não está.

2.8.1.5. Caixas de seleção

cases à cocher
<input type="checkbox" name="C1" value="um">1
<input type="checkbox" name="C2" value="dois" checked>2
<input type="checkbox" name="C3" value="três">3

Image

balise HTML
<input type="checkbox" atributo2="valor2" ....>texto
exibe uma caixa de seleção com texto ao lado.
attributs
name="C1": nome do controlo. As caixas de seleção podem ou não ter o mesmo nome. As caixas com o mesmo nome formam um grupo de caixas associadas.
value="valor": valor atribuído à caixa de seleção. Não se deve confundir este valor com o texto exibido ao lado do botão de opção. Este último destina-se apenas à exibição.
checked: se esta palavra-chave estiver presente, o botão de opção está marcado; caso contrário, não está.

2.8.1.6. Lista suspensa (combo)

Combo
<select size="1" name="cmbValeurs">
<option>choix1</option>
<option selected>opção2</option>
<option>choix3</option>
</select>

Image

balise HTML
<select size=".." name="..">
<option [selected]>...</option>
...
</select>
exibe numa lista os textos contidos entre as balizas <option>...</option>
attributs
name="cmbValeurs": nome do controlo.
size="1": número de elementos da lista visíveis. size="1" transforma a lista no equivalente a uma caixa de seleção.
selected: se esta palavra-chave estiver presente para um elemento da lista, este aparece selecionado na lista. No nosso exemplo acima, o elemento da lista choix2 aparece como o elemento selecionado da caixa de combinação quando esta é apresentada pela primeira vez.

2.8.1.7. Lista de seleção única

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>
exibe numa lista os textos entre as balizas <option>...</option>
attributs
os mesmos que para a lista suspensa que apresenta apenas um elemento. Este controlo difere da lista suspensa anterior apenas pelo seu atributo size>1.

2.8.1.8. Lista de seleção múltipla

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>
exibe numa lista os textos entre as balizas <option>...</option>
attributs
múltiplo: permite a seleção de vários elementos na lista. No exemplo acima, os elementos liste1 e liste3 estão ambos selecionados.

2.8.1.9. Botão do tipo «button»

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

Image

balise HTML
<input type="button" value="..." name="..." onclick="effacer()" ....>
attributs
type="button": define um controlo de botão. Existem outros dois tipos de botão: os tipos submit e reset.
value="Apagar": o texto exibido no botão
onclick="função()": permite definir uma função a executar quando o utilizador clica no botão. Esta função faz parte dos scripts definidos no documento web apresentado. A sintaxe anterior é uma sintaxe javascript. Se os scripts forem escritos em VBScript, deve escrever-se onclick="função" sem os parênteses. A sintaxe torna-se idêntica se for necessário passar parâmetros para a função: onclick="função(val1, val2,...)"
No nosso exemplo, um clique no botão Effacer chama a seguinte função JavaScript effacer:
    <script language="JavaScript">
        function effacer(){
          alert("Vous avez cliqué sur le bouton Effacer");
      }//apagar
        </script>
A função effacer apresenta a seguinte mensagem:

2.8.1.10. Botão do tipo «submit»

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

Image

balise HTML
<input type="submit" value="Enviar" name="cmdRenvoyer">
attributs
type="submit": define o botão como um botão para enviar os dados do formulário para o servidor web. Quando o utilizador clicar neste botão, o navegador enviará os dados do formulário para o URL definido no atributo action da tag <form>, de acordo com o método definido pelo atributo method dessa mesma tag.
value="Enviar": o texto exibido no botão

2.8.1.11. Botão do tipo «reset»

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

Image

balise HTML
<input type="reset" value="Restaurar" name="cmdRétablir">
attributs
type="reset": define o botão como um botão de reinicialização do formulário. Quando o utilizador clicar neste botão, o navegador irá repor o formulário no estado em que o recebeu.
value="Restaurar": o texto exibido no botão

2.8.1.12. Campo oculto

champ caché
<input type="hidden" name="secret" value="uneValeur">
balise HTML
<input type="hidden" name="..." value="...">
attributs
type="hidden": indica que se trata de um campo oculto. Um campo oculto faz parte do formulário, mas não é apresentado ao utilizador. No entanto, se este solicitasse ao seu navegador a visualização do código-fonte, veria a presença da baliza <input type="hidden" value="..."> e, consequentemente, o valor do campo oculto.
value="umValor": valor do campo oculto.
Qual é a utilidade do campo oculto? Este permite que o servidor web guarde informações ao longo das solicitações de um cliente. Consideremos uma aplicação de compras na web. O cliente compra um primeiro artigo art1 na quantidade q1 numa primeira página de um catálogo e, em seguida, passa para uma nova página do catálogo. Para se lembrar de que o cliente comprou q1 artigos art1, o servidor pode colocar estas duas informações num campo oculto do formulário web da nova página. Nesta nova página, o cliente compra os artigos q2 e art2. Quando os dados deste segundo formulário forem enviados para o servidor (submit), este irá receber não só a informação (q2,art2), mas também (q1,art1), que também faz parte do formulário como um campo oculto não modificável pelo utilizador. O servidor web irá então colocar num novo campo oculto as informações (q1,art1) e (q2,art2) e enviar uma nova página do catálogo. E assim sucessivamente.

2.8.2. Envio de valores de um formulário de um cliente web para um servidor web

No estudo anterior, referimos que o cliente web dispõe de dois métodos para enviar a um servidor web os valores de um formulário que apresentou: os métodos GET e POST. Vejamos, através de um exemplo, a diferença entre os dois métodos. Retomamos o exemplo anterior e tratamo-lo da seguinte forma:

  1. um navegador solicita o URL do exemplo a um servidor web
  2. assim que o formulário for obtido, preenchemo-lo
  3. antes de enviar os valores do formulário para o servidor web clicando no botão Envoyer do tipo submit, desligamos o servidor web e substituímo-lo pelo servidor genérico TCP já utilizado anteriormente. Recorde-se que este servidor exibe no ecrã as linhas de texto que lhe são enviadas pelo cliente web. Assim, poderemos ver exatamente o que o navegador envia.

O formulário é preenchido da seguinte forma:

Image

O URL utilizado para este documento é o seguinte:

Image

2.8.2.1. Método GET

O documento HTML está configurado para que o navegador utilize o método GET para enviar os valores do formulário ao servidor web. Por isso, escrevemos:

    <form method="GET" >

Desligamos o servidor web e iniciamos o nosso servidor genérico TCP na porta 81:

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

Agora, voltamos ao nosso navegador para enviar os dados do formulário para o servidor web utilizando o botão Envoyer:

Image

Eis, então, o que o servidor genérico TCP recebe:

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

Tudo está no primeiro cabeçalho HTTP enviado pelo navegador:

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

Vê-se que é muito mais complexo do que aquilo com que nos deparámos até agora. Encontramos aqui a sintaxe GET URL HTTP/1.1, mas numa forma específica: GET URL?param1=valor1&param2=valor2&... HTTP/1.1, em que os parami são os nomes dos controlos do formulário web e os valores são os valores que lhes estão associados. Vamos analisá-los mais de perto. Apresentamos abaixo uma tabela com três colunas:

  • coluna 1: apresenta a definição de um controlo HTML do exemplo
  • coluna 2: apresenta a visualização desse controlo num navegador
  • coluna 3: apresenta o valor enviado ao servidor pelo navegador para o controlo da coluna 1, na forma em que aparece na solicitação GET do exemplo
controlo HTML
visual
valor(es) devolvido(s)
<input type="radio" value="Sim" name="R1">Sim
<input type="radio" name="R1" value="não" checked>Não
R1=Sim
- o valor do atributo value do botão de opção selecionado pelo utilizador.
<input type="checkbox" name="C1" value="um">1
<input type="checkbox" name="C2" value="dois" checked>2
<input type="checkbox" name="C3" value="três">3
C1=um
C2=dois
- valores dos atributos value das caixas de seleção marcadas pelo utilizador
<input type="text" name="txtSaisie" size="20" value="algumas palavras">
txtSaisida=programação+web
- texto digitado pelo utilizador no campo de introdução. Os espaços foram substituídos pelo sinal +
<input type="password" name="txtMdp" size="20" value="unMotDePasse">
txtMdp=istoé-secreto
- texto digitado pelo utilizador no campo de introdução
<textarea rows="2" name="areaSaisie" cols="20">
linha1
linha 2
linha 3
</textarea>
areaSaisie=os+fundamentos+da%0D%0A
programação+web
- texto digitado pelo utilizador no campo de introdução. %OD%OA é o marcador de fim de linha. Os espaços foram substituídos pelo sinal +
<select size="1" name="cmbValeurs">
<option>opção1</option>
<option selected>opção 2</option>
<option>opção3</option>
</select>
cmbValores=opção3
- valor escolhido pelo utilizador na lista de seleção única
<select size="3" name="lst1">
<option selected>lista1</option>
<option>lista2</option>
<option>lista3</option>
<option>lista4</option>
<option>lista5</option>
</select>
lst1=lista3
- valor escolhido pelo utilizador na lista de seleção única
<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
- valores selecionados pelo utilizador na lista de seleção múltipla
<input type="submit" value="Enviar" name="cmdRenvoyer">
 
cmdRenvoyer=Enviar
- nome e atributo value do botão utilizado para enviar os dados do formulário para o servidor
<input type="hidden" name="secret" value="uneValeur">
 
secret=umValor
- atributo value do campo oculto

Vamos repetir o mesmo procedimento, mas desta vez deixando que o servidor web elabore a resposta, para vermos qual é o resultado. A página devolvida pelo servidor web é a seguinte:

Image

É exatamente a mesma que a recebida inicialmente, antes de preencher o formulário. Para compreender porquê, é necessário analisar novamente o URL solicitado pelo navegador quando o utilizador clica no botão 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

A URL solicitada é /html/balises.htm. Além disso, são passados para esta URL os valores do formulário. Por enquanto, o URL /html/balises.htm, que é uma página estática, não utiliza esses valores. Assim, o GET anterior é equivalente a

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

e é por isso que o servidor nos reenviou novamente a página inicial. Note-se que o navegador exibe corretamente a página URL completa que foi solicitada:

Image

2.8.2.2. Método POST

O documento HTML está programado para que o navegador utilize agora o método POST para enviar os valores do formulário ao servidor web:

    <form method="POST" >

Desligamos o servidor web e iniciamos o servidor genérico TCP (já mencionado, mas ligeiramente modificado para a ocasião) na porta 81:

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

Agora, voltamos ao nosso navegador para enviar os dados do formulário para o servidor web através do botão «Enviar»:

Image

Eis então o que o servidor genérico TCP recebe:

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

Em comparação com o que já conhecemos, observamos as seguintes alterações na solicitação do navegador:

  1. O cabeçalho inicial HTTP já não é GET, mas sim POST. A sintaxe é POST URL HTTP/1.1, em que URL é o URL solicitado pelo navegador. Ao mesmo tempo, POST significa que o navegador tem dados para transmitir ao servidor.
  2. A linha Content-Type: application/x-www-form-urlencoded indica que tipo de dados o navegador irá enviar. Trata-se de dados de formulário (x-www-form) codificados (urlencoded). Esta codificação faz com que alguns caracteres dos dados transmitidos sejam transformados, de modo a evitar erros de interpretação por parte do servidor. Assim, o espaço é substituído por +, o símbolo de fim de linha por %OD%OA,... De um modo geral, todos os caracteres contidos nos dados e suscetíveis de uma interpretação errada por parte do servidor (&, +, %, ...) são transformados em %XX, em que XX é o seu código hexadecimal.
  3. A linha «Content-Length: 210» indica ao servidor quantos caracteres o cliente lhe irá enviar assim que os cabeçalhos HTTP, c.a.d, terminarem, após a linha vazia que assinala o fim dos cabeçalhos.
  4. Os dados (210 caracteres): R1=Sim&C1=um&C2=dois&txtSaisie=programação+web&txtMdp=istoé-secreto&areaSaisie=as+bases+da%0D%0Aprogramação+web&cmbValeurs=escolha3&lst1=lista3&lst2=lista1&lst2=lista3&cmdRenvoyer=Enviar&secret=uneValeur

Verifica-se que os dados transmitidos por POST têm o mesmo formato que os transmitidos por GET.

Existe algum método melhor do que o outro? Vimos que, se os valores de um formulário fossem enviados pelo navegador com o método GET, o navegador exibia no seu campo Adresse o URL solicitado na forma URL?param1=val1&param2=val2&.... Isto pode ser visto como uma vantagem ou uma desvantagem:

  • uma vantagem se se quiser permitir que o utilizador coloque esse URL configurado nos seus favoritos
  • uma desvantagem se não se quiser que o utilizador tenha acesso a determinadas informações do formulário, tais como, por exemplo, os campos ocultos

Posteriormente, utilizaremos quase exclusivamente o método POST nos nossos formulários.

2.8.2.3. Recuperação dos valores de um formulário Web

Uma página estática solicitada por um cliente que, além disso, envia parâmetros através de POST ou GET não pode, de forma alguma, recuperar esses parâmetros. Apenas um programa pode fazê-lo e será ele que se encarregará de gerar uma resposta para o cliente, uma resposta que será dinâmica e, geralmente, dependente dos parâmetros recebidos. Este é o domínio da programação web, domínio que abordaremos mais detalhadamente no capítulo seguinte com a apresentação das tecnologias Java de programação web: os servlets e as páginas JSP.