Skip to content

2. O Básico

Neste capítulo, apresentamos os conceitos básicos da programação web. O seu objetivo principal é introduzir os princípios fundamentais da programação web antes de os pôr em prática com uma linguagem e um ambiente específicos. Inclui inúmeros exemplos que o encorajamos a experimentar, a fim de, gradualmente, «apreender» a filosofia do desenvolvimento web.

2.1. : Componentes de uma aplicação Web

Image

Número
Função
Exemplos comuns
1
SO do servidor
Linux, Windows
2
Servidor Web
Apache (Linux, Windows)
IIS (NT), PWS (Win9x)
3
Scripts do 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 - 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
SO do cliente
Linux, Windows
6
Navegador Web
Netscape, Internet Explorer
7
Scripts executados no lado do cliente dentro do navegador.
Estes scripts não têm acesso aos discos do computador do cliente.
VBScript (IE)
JavaScript (IE, Netscape)
PerlScript (IE)
Applets Java

2.2. As trocas de dados numa aplicação web com um formulário

Image

Máquina do clienteServidor

Número
Função
1
O navegador solicita um URL pela primeira vez (http://machine/url). Não são passados parâmetros.
2
O servidor web envia a página web para essa URL. Pode ser estática ou gerada dinamicamente por um script do lado do servidor (SA) que pode ter utilizado conteúdo de bases de dados (SB, SC). Aqui, o script irá detetar que a URL foi solicitada sem quaisquer parâmetros e irá gerar a página web inicial.
O navegador recebe a página e exibe-a (CA). Os scripts do lado do navegador (CB) podem ter modificado a página inicial enviada pelo servidor. Em seguida, através de interações entre o utilizador (CD) e os scripts (CB), a página web será modificada. Em particular, os formulários serão preenchidos.
3
O utilizador submete os dados do formulário, que devem então ser enviados para o servidor web. O navegador solicita a URL inicial ou outra, conforme apropriado, e transmite simultaneamente os valores do formulário para o servidor. Pode utilizar dois métodos para isso: GET e POST. Ao receber o pedido do cliente, o servidor aciona o script (SA) associado à URL solicitada, que irá detetar os parâmetros e processá-los.
4
O servidor entrega a página web gerada pelo programa (SA, SB, SC). Este passo é idêntico ao passo 2 anterior. A comunicação prossegue agora de acordo com os passos 2 e 3.

2.3. Recursos úteis sobre o

Segue-se uma lista de recursos para a instalação e utilização de determinadas ferramentas de desenvolvimento web. Um apêndice fornece orientações de instalação para estas ferramentas.

Servidor Apache
http://www.apache.org
- Apache: Instalação e Implementação, O'Reilly
Servidor 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 incluída no Active Perl
PHP
http://www.php.net
- Programação Web com PHP, Lacroix, Eyrolles
- Manual do utilizador 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 a Web e as bases 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
Bases de dados
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. Notas

A seguir, assumiremos que várias ferramentas foram instaladas e utilizaremos a seguinte notação:

notação
significado
<apache>
raiz da árvore de diretórios do servidor Apache
<apache-DocumentRoot>
Diretório raiz das páginas web servidas pelo Apache. As páginas web devem estar localizadas neste diretório raiz. 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, onde podem ser colocados os 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 servidas pelo PWS. As páginas web devem estar localizadas sob esta raiz. Assim, o URL http://localhost/page1.htm corresponde ao ficheiro <pws-DocumentRoot>\page1.htm.
<perl>
Raiz da árvore de diretórios do Perl. O executável perl.exe está normalmente localizado em <perl>\bin.
<php>
A raiz da árvore de diretórios do PHP. O executável php.exe está normalmente localizado no diretório <php>.
<java>
Raiz da árvore de diretórios Java. Os executáveis Java estão localizados em <java>\bin.
<tomcat>
Raiz do servidor Tomcat. Podem ser encontrados exemplos de servlets em <tomcat>\webapps\examples\servlets e exemplos de páginas JSP em <tomcat>\webapps\examples\jsp

Para cada uma destas ferramentas, consulte o apêndice, que fornece orientações de 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 outro lado, é gerada «em tempo real» pelo servidor web. Nesta secção, apresentamos vários testes utilizando diferentes servidores web e linguagens de programação para demonstrar a universalidade do conceito da web.

2.5.1. Página HTML estática (HyperText Markup Language)

Considere 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

  • Inicie o servidor Apache

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

  • Aceda ao URL http://localhost/essai1.html num navegador

  • Pára o servidor Apache

  • Inicie o servidor PWS

  • Coloque o script essai1.html em <pws-DocumentRoot>

  • Aceda ao URL http://localhost/essai1.html num 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

  • Inicie o servidor PWS

  • Coloque o script essai2.asp em <pws-DocumentRoot>

  • Aceda ao URL http://localhost/essai2.asp utilizando 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 para o executável perl.exe. Poderá ser necessário ajustá-lo, se for o caso. Uma vez executado por um servidor web, o script produz a seguinte página:

Image

O teste

  • Servidor Web: Apache

  • Para referência, consulte o ficheiro de configuração srm.conf ou httpd.conf (dependendo da sua versão do Apache) em <apache>\confs e procure a linha que menciona cgi-bin para determinar o diretório <apache-cgi-bin> onde deve colocar o essai3.pl.

  • Coloque o script essai3.pl em <apache-cgi-bin>

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

Note que a página Perl demora mais tempo a carregar 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 na memória de forma permanente.

2.5.4. Um script PHP (Personal Home Page)

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 produz a seguinte página web:

Testes

Image

Image

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

  • Para referência, verifique as linhas de configuração do PHP

  • Inicie o servidor Apache

  • Coloque o ficheiro essai4.php em <apache-DocumentRoot>

  • Aceda ao URL http://localhost/essai4.php

  • Inicie o servidor PWS

  • Para referência, verifique a configuração do PWS relativa ao PHP

  • Coloque o ficheiro essai4.php em <pws-DocumentRoot>\php

  • Solicite a URL http://localhost/essai4.php

2.5.5. Um script JSP

O script heure.jsp

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

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

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

<% // code HTML %>
<html>
  <head>
     <title>Page JSP affichant l'heure</title>
  </head>
  <body>
     <center>
     <h1>Une page JSP générée dynamiquement</h1>
     <h2>Il est <%=heures%>:<%=minutes%>:<%=secondes%></h2>
     <br>
     <h3>A chaque fois que vous rechargez la page, l'heure change</h3>
  </body>
</html>

Uma vez executado pelo servidor web, este script produz a seguinte página:

Image

Testes

  • Coloque 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
  • Aceda ao URL 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. Este é o objetivo da programação web.
  • as linguagens e os servidores web utilizados podem variar. Atualmente, observam-se as seguintes tendências principais:
    • as combinações Apache/PHP (Windows, Linux) e IIS/PHP (Windows)
    • a tecnologia ASP.NET em plataformas Windows, que combina o servidor IIS com uma linguagem .NET (C#, VB.NET, etc.)
    • A tecnologia Java Servlet e as páginas JSP a funcionar em vários servidores (Tomcat, Apache, IIS) e em várias plataformas (Windows, Linux). É esta última tecnologia que será abordada com maior detalhe neste documento.

2.6. Scripts do lado do navegador

Uma página HTML pode conter scripts que são executados pelo navegador. Existem muitas linguagens de script do lado do navegador. Aqui estão algumas:

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, no 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 contém não só código HTML, mas também um programa destinado a ser executado pelo navegador que carrega 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 tags <script> e </script> são utilizadas para delimitar scripts dentro de uma página HTML. Estes scripts podem ser escritos em várias linguagens, e o atributo language da tag <script> especifica a linguagem utilizada. Neste caso, é VBScript. Não entraremos em detalhes sobre esta linguagem. O script acima define uma função chamada react que exibe uma mensagem. Quando é que esta função é chamada? A seguinte linha de código HTML diz-nos:

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

O atributo onclick especifica o nome da função a ser chamada quando o utilizador clica no botão OK. Assim que o navegador carregar esta página e o utilizador clicar no botão OK, aparecerá a seguinte página:

Image

Testes

Apenas o Internet Explorer é capaz de executar scripts VBScript. O Netscape requer complementos para o fazer. Podemos realizar os seguintes testes:

  • Servidor Apache

  • Script vbs1.html em <apache-DocumentRoot>

  • Solicitar o URL http://localhost/vbs1.html utilizando o Internet Explorer

  • Servidor PWS

  • Script vbs1.html em <pws-DocumentRoot>

  • Solicite a URL http://localhost/vbs1.html utilizando o Internet Explorer

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>

Esta página é idêntica à anterior, exceto que substituímos o VBScript pelo JavaScript. O JavaScript tem a vantagem de ser suportado tanto pelo Internet Explorer como pelo Netscape. A sua execução produz os mesmos resultados:

Image

Os testes

  • Servidor Apache

  • Script js1.html em <apache-DocumentRoot>

  • Solicite o URL http://localhost/js1.html utilizando o Internet Explorer ou o Netscape

  • Servidor PWS

  • Script js1.html em <pws-DocumentRoot>

  • Aceda ao URL http://localhost/js1.html utilizando o Internet Explorer ou o Netscape

2.7. Comunicação cliente-servidor

Voltemos ao nosso diagrama inicial que ilustra os componentes de uma aplicação web:

Aqui, estamos a concentrar-nos nas trocas entre o computador cliente e o servidor. Estas ocorrem através de uma rede, e vale a pena rever a estrutura geral das trocas entre dois computadores remotos.

2.7.1. O modelo OSI

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

Cada camada recebe serviços da camada abaixo dela e fornece os seus próprios serviços à camada acima dela. Suponha que duas aplicações localizadas em máquinas diferentes, A e B, queiram comunicar: fazem-no na camada de Aplicação. Não precisam de conhecer todos os detalhes de como a rede funciona: cada aplicação passa a informação que deseja transmitir para a camada abaixo dela: a camada de Apresentação. A aplicação, portanto, só precisa de conhecer as regras para interagir com a camada de Apresentação. Uma vez que a informação está na camada de Apresentação, é passada de acordo com outras regras para a camada de Sessão, e assim por diante, até que a informação chegue ao meio físico e seja fisicamente transmitida para a máquina de destino. Aí, passará pelo processo inverso ao que passou na máquina de envio.

Em cada camada, o processo emissor responsável pelo envio da informação envia-a a um processo recetor na outra máquina pertencente à mesma camada que ele próprio. Faz-o de acordo com certas regras conhecidas como protocolo da camada. Temos, portanto, o seguinte diagrama de comunicação final:

As funções das diferentes camadas são as seguintes:

Física
Assegura a transmissão de bits através de um meio físico. Esta camada inclui equipamentos terminais de processamento de dados (DPTE), tais como terminais ou computadores, bem como equipamentos de terminação de circuitos de dados (DCTE), tais como moduladores/demoduladores, multiplexadores e concentradores. Os pontos-chave neste 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).
Camada de Ligação de Dados
Oculta as características físicas da Camada Física. Deteta e corrige erros de transmissão.
Rede
Gere o caminho que a informação enviada pela rede deve seguir. Isto denomina-se encaminhamento: determinar a rota que a informação deve seguir para chegar ao seu destino.
Transporte
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 a multiplexação: a camada de transporte pode utilizar uma única ligação de rede (de máquina para máquina) para transmitir dados pertencentes a várias aplicações.
Sessão
Esta camada fornece serviços que permitem a uma aplicação abrir e manter uma sessão de trabalho numa máquina remota.
Apresentação
O seu objetivo é padronizar a representação dos dados entre diferentes máquinas. Assim, os dados provenientes da máquina A serão «formatados» pela camada de apresentação da máquina A de acordo com um formato padrão antes de serem enviados pela rede. Ao chegarem à camada de apresentação da máquina de destino B, que os reconhecerá graças ao seu formato padrão, serão reformatados de modo a que a aplicação na máquina B os possa reconhecer.
Aplicação
Neste nível, encontramos aplicações que estão geralmente próximas do utilizador, tais como o e-mail 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) desempenha as funções das camadas 1 e 2 do modelo OSI
  • a camada IP (Protocolo de Internet) desempenha as funções da camada 3 (rede)
  • a camada TCP (Protocolo de Controlo de Transmissão) 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 máquinas cheguem ao seu destino. Se isso não acontecer, reenvia os pacotes perdidos. O protocolo UDP não desempenha esta tarefa, pelo que cabe ao programador da aplicação fazê-lo. É por isso que, na Internet — que não é uma rede 100% fiável —, o protocolo TCP é o mais utilizado. A isto chama-se uma rede TCP-IP.
  • A camada de Aplicação abrange as funções das camadas 5 a 7 do modelo OSI.

As aplicações web residem na camada de Aplicação e, por isso, dependem dos protocolos TCP/IP. As camadas de Aplicação das máquinas cliente e servidor trocam mensagens, que são depois transferidas para as camadas 1 a 4 do modelo para serem encaminhadas para o seu destino. Para comunicarem entre si, as camadas de Aplicação de ambas as máquinas têm de «falar» a mesma língua ou protocolo. O protocolo utilizado pelas aplicações web denomina-se HTTP (HyperText Transfer Protocol). Trata-se de um protocolo baseado em texto, o que significa que as máquinas trocam linhas de texto através da rede para comunicarem. Estas trocas são padronizadas, o que significa que o cliente dispõe de um conjunto de mensagens para indicar ao servidor exatamente o que pretende, e o servidor também dispõe de um conjunto de mensagens para fornecer a sua resposta ao cliente. Esta troca de mensagens assume a seguinte forma:

Cliente --> Servidor

Quando o cliente faz um pedido ao servidor web, envia

  1. linhas de texto no formato HTTP para indicar o que pretende
  2. uma linha vazia
  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 comunicações seguem, portanto, o mesmo formato em ambas as direções. Em ambos os casos, pode ser enviado um documento, embora seja raro um cliente enviar um documento para o servidor. Mas o protocolo HTTP permite isso. É isso que permite, por exemplo, que os assinantes de um ISP carreguem vários documentos para o seu site pessoal hospedado por esse ISP. Os documentos trocados podem ser de qualquer tipo. Considere um navegador a solicitar uma página web que contenha imagens:

  1. o navegador liga-se ao servidor web e solicita a página que deseja. Os recursos solicitados são identificados de forma única por URLs (Uniform Resource Locators). O navegador envia apenas cabeçalhos HTTP e nenhum documento.
  2. O servidor responde. Primeiro, envia cabeçalhos HTTP indicando que tipo de resposta está a enviar. Esta pode ser um erro, caso a página solicitada não exista. Se a página existir, o servidor indicará nos cabeçalhos HTTP da sua resposta que irá enviar um documento HTML (HyperText Markup Language) a seguir a eles. Este documento é uma sequência de linhas de texto em formato HTML. O texto HTML contém tags (marcadores) que fornecem ao navegador instruções sobre como apresentar o texto.
  3. O cliente sabe, a partir dos cabeçalhos HTTP do servidor, que irá receber um documento HTML. Ele irá analisar este documento e poderá perceber que este contém referências a imagens. Estas imagens não estão incluídas 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 passo 1, exceto que o recurso solicitado é diferente. O servidor processará esta solicitação enviando a imagem solicitada ao cliente. 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 recupera a imagem enviada. Os passos 3 e 4 serão repetidos até que o cliente (normalmente 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

Aqui, vamos explorar como um servidor web responde aos pedidos dos seus clientes. O serviço web ou serviço HTTP é um serviço TCP/IP que normalmente opera na porta 80. Pode operar numa porta diferente. Nesse caso, o navegador do cliente teria de especificar essa porta no URL que solicita. Um URL segue geralmente este formato:

protocolo://máquina[:porta]/caminho/informação

onde

protocolo
http para o serviço web. Um navegador também pode atuar como cliente para FTP, news, Telnet e outros serviços.
máquina
nome da máquina que hospeda o serviço web
porta
Porta do serviço web. Se for 80, o número da porta pode ser omitido. Este é o caso mais comum
caminho
caminho para o recurso solicitado
info
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. Estabelece uma ligação TCP/IP com a máquina e a porta especificadas na parte máquina[:porta] da URL. Estabelecer uma ligação TCP/IP significa criar um «canal» de comunicação entre duas máquinas. Assim que este canal for estabelecido, toda a informação trocada entre as duas máquinas passará por ele. A criação deste canal TCP/IP ainda não envolve o protocolo HTTP da Web.
  2. Assim que a ligação TCP/IP é estabelecida, o cliente envia o seu pedido ao servidor Web, enviando linhas de texto (comandos) no formato HTTP. Envia a parte path/info da URL para o servidor
  3. O servidor responderá da mesma forma e através da mesma ligação
  4. Uma das duas partes decidirá encerrar a ligação. Isto depende do protocolo HTTP utilizado. Com o HTTP 1.0, o servidor encerra a ligação após cada uma das suas respostas. Isto obriga um cliente que precise de efetuar múltiplas solicitações para recuperar os vários documentos que compõem uma página web a abrir uma nova ligação para 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 diga para a encerrar. Pode, assim, recuperar todos os documentos de uma página web utilizando uma única ligação e encerrar a ligação por si próprio assim que o último documento tiver sido obtido. O servidor detetará este encerramento e encerrará também a ligação.

Para explorar as trocas entre um cliente e um servidor web, utilizaremos um cliente TCP genérico. Trata-se de um programa que pode atuar como cliente para qualquer serviço que utilize um protocolo de comunicação baseado em texto, como o protocolo HTTP. Estas linhas de texto serão digitadas pelo utilizador através do teclado. Isto requer que o utilizador conheça o protocolo de comunicação do serviço ao qual está a tentar aceder. A resposta do servidor é então apresentada no ecrã. O programa foi escrito em Java e pode ser encontrado no apêndice. Aqui, utilizamo-lo numa janela DOS no Windows e chamamo-lo da seguinte forma:

java clientTCPgenerique máquina porta

com

máquina
nome da máquina onde o serviço a contactar está a ser executado
porta
porta onde o serviço é fornecido

Com estas duas informações, o programa abrirá uma ligação TCP/IP à máquina e à porta especificadas. Esta ligação será utilizada para trocar 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 ocorrer um diálogo diretamente entre o utilizador ao teclado e o servidor web. Vamos experimentar isto com os exemplos já apresentados. Tínhamos criado a seguinte página HTML estática:

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

que visualizamos num navegador:

Image

Podemos ver que o URL solicitado é: http://localhost:81/essais/essai1.html. O servidor web é, portanto, o localhost (=máquina local) na porta 81. Se visualizarmos o código-fonte HTML desta página web (Ver/Código-fonte), vemos o texto HTML que foi originalmente criado:

Image

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

Quando o cliente é iniciado utilizando o comando java clientTCPgenerique localhost 81, é estabelecida uma ligação entre o programa e o servidor web em execução na mesma máquina (localhost) na porta 81. A comunicação cliente-servidor no formato HTTP pode agora começar. Recorde-se que estes pedidos têm três componentes:

  1. Cabeçalhos HTTP
  2. linha vazia
  3. dados opcionais

No nosso exemplo, o cliente envia apenas uma solicitação:

GET /tests/test1.html HTTP/1.0

Esta linha tem três componentes:

GET
Comando HTTP para solicitar um recurso. Existem outros:
HEAD solicita um recurso, mas limita-se aos cabeçalhos HTTP na resposta do servidor. O recurso em si não é enviado.
PUT permite que o cliente envie um documento para o servidor
/tests/test1.html
recurso solicitado
HTTP/1.0
Versão do protocolo HTTP utilizada. Aqui, 1.0. Isto significa que o servidor encerrará a ligação assim que enviar 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 está concluída. Aqui, o cliente terminou. Não tem nenhum documento para enviar. A resposta do servidor começa então, consistindo, no nosso exemplo, em todas as linhas que começam com o símbolo <--. Primeiro, envia uma série de cabeçalhos HTTP seguidos por 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 suporta a versão 1.1 do HTTP
  • que possui o recurso solicitado (código de estado 200, mensagem OK)
Data: ...
a data/hora da resposta
Servidor:
o servidor identifica-se. Aqui trata-se de um servidor Apache
Última modificação:
data da última modificação do recurso solicitado pelo cliente
ETag:
...
Accept-Ranges: bytes
unidade de medida dos dados enviados. Aqui, o byte
Content-Length: 161
número de bytes no documento a enviar 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 test1.html

08/07/2002  10:00                  161 essai1.html
Conexão: encerrada
O servidor indica que irá encerrar a ligação assim que o documento for enviado
Tipo de conteúdo: text/html
O servidor indica que irá enviar texto (text) no formato HTML (html).

O cliente recebe estes cabeçalhos HTTP e sabe agora que irá receber 161 bytes que representam um documento HTML. O servidor envia estes 161 bytes imediatamente após a linha em branco que marcou 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>

Aqui, reconhecemos o ficheiro HTML que foi inicialmente construído. Se o nosso cliente fosse um navegador, após receber estas linhas de texto, interpretá-las-ia para apresentar a seguinte página ao utilizador:

Image

Vamos usar novamente o nosso cliente TCP genérico 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
<--

Obtemos o mesmo resultado que antes, sem o documento HTML. Note-se que, na sua solicitação HEAD, o cliente indicou que estava a utilizar a versão 1.1 do HTTP. Isto obriga-o a enviar um segundo cabeçalho HTTP especificando o par máquina:porta que o cliente pretende consultar: Host: localhost:81.

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

Image

O ficheiro univ01.gif tem 3167 bytes:

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

Agora vamos utilizar o cliente TCP genérico:


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

Observe os seguintes pontos na resposta do servidor:

HEAD
  • Solicitamos apenas os cabeçalhos HTTP do recurso. Isto porque uma imagem é um ficheiro binário, não um ficheiro de texto, e exibi-la no ecrã como texto não produz nada legível.
Content-Length: 3167
  • Este é o tamanho do ficheiro univ01.gif
Content-Type: image/gif
  • O servidor informa ao seu cliente que enviará um documento do tipo image/gif, ou seja, uma imagem no formato GIF. Se a imagem estivesse no formato JPEG, o tipo de documento teria sido image/jpeg. Os tipos de documentos são padronizados e são chamados de tipos MIME (Multi-purpose Mail Internet Extension).

2.7.3.2. Um pedido de um cliente HTTP

Agora, vamos fazer a seguinte pergunta: se quisermos escrever um programa que «comunique» com um servidor web, que comandos deve este enviar ao servidor web para obter um determinado recurso? Já começámos a responder a esta questão nos exemplos anteriores. Encontrámos três comandos:

GET recurso protocolo
  • para solicitar um recurso específico utilizando uma versão específica do protocolo HTTP. O servidor envia uma resposta no formato HTTP, seguida de uma linha em branco e, em seguida, do recurso solicitado
HEAD recurso protocolo
  • igual ao anterior, exceto que aqui a resposta se limita aos cabeçalhos HTTP e à linha em branco
host:máquina:porta
  • para especificar (protocolo HTTP 1.1) a máquina e a porta do servidor web consultado

Existem outros comandos. Para os explorar, vamos agora utilizar um servidor TCP genérico. Trata-se de um programa escrito em Java, que também poderá encontrar no apêndice. É executado através do comando: java genericTCPserver listeningPort, em que listeningPort é a porta à qual os clientes devem ligar-se. O programa genericTCPserver

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

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

Agora vamos abrir um navegador e introduzir o URL http://localhost:88/exemple.html. O navegador irá então ligar-se à porta 88 na máquina localhost e solicitar a página /example.html:

Image

Agora vamos dar uma olhada na janela do nosso servidor, que exibe o que o cliente enviou (algumas linhas específicas da operação do programa serverTCPgenerique foram omitidas por uma questão de simplicidade):


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 símbolo <-- são as enviadas pelo cliente. Isto revela cabeçalhos HTTP que ainda não encontrámos:

Accept:
  • uma lista de tipos de documentos MIME que o navegador consegue processar.
Accept-language:
  • o idioma preferido para os documentos.
Accept-Encoding:
  • os tipos de codificação para documentos que o navegador consegue processar
User-Agent:
  • identidade do cliente
Conexão:
  • Close: o servidor encerrará a ligação após enviar a sua resposta
  • Keep-Alive: a ligação permanecerá aberta após receber a resposta do servidor. Isto permitirá ao navegador solicitar os outros documentos necessários para construir a página sem ter de restabelecer uma ligação.

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

Vamos criar uma resposta para o nosso cliente. O utilizador ao teclado é, neste caso, o servidor e pode criar uma resposta manualmente. Lembre-se da resposta enviada 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 criar manualmente (no teclado) uma resposta semelhante. As linhas que começam com --> : são enviadas para o 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 «end» é específico do funcionamento do programa serverTCPgenerique. Interrompe a execução do programa e encerra a ligação entre o servidor e o cliente. Na nossa resposta, limitámo-nos aos seguintes cabeçalhos HTTP:

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

Não especificamos o tamanho do ficheiro que estamos a enviar (Content-Length), mas indicamos simplesmente que iremos encerrar a ligação (Connection: close) após o envio. Isto é suficiente para o navegador. Quando verificar que a ligação foi encerrada, saberá que a resposta do servidor está completa e apresentará a página HTML que lhe foi enviada. A página é a seguinte:

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

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

Image

Se clicar em «Ver/Fonte» acima para ver o que o navegador recebeu, obtém:

Image

ou seja, exatamente o que foi enviado pelo servidor genérico.

2.8. HTML

Um navegador da Web pode exibir vários documentos, sendo os mais comuns os documentos HTML (HyperText Markup Language). Estes consistem em texto formatado com tags na forma <tag>texto</tag>. Assim, o texto <B>importante</B> exibirá o texto «importante» em negrito. Existem tags independentes, como a tag <hr>, que exibe uma linha horizontal. Não iremos rever todas as tags que podem ser encontradas no texto HTML. Existem muitos programas de software 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 para um layout criado utilizando o rato e controlos predefinidos. Pode, assim, inserir (utilizando o rato) uma tabela na página e, em seguida, visualizar o código HTML gerado pelo software para descobrir as tags a utilizar na definição de uma tabela numa página web. Não é mais complicado do que isso. Além disso, o conhecimento de HTML é essencial, uma vez que as aplicações web dinâmicas têm de gerar elas próprias o código HTML para enviar aos clientes web. Este código é gerado programaticamente e, naturalmente, é necessário saber o que gerar para que o cliente receba 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, este conhecimento é necessário e pode ser adquirido através da utilização de editores de páginas Web WYSIWYG, como o Word, o FrontPage, o DreamWeaver e dezenas de outros. Outra forma de descobrir as complexidades do HTML é navegar na Web e visualizar o código-fonte de páginas que apresentem elementos interessantes que ainda não tenha encontrado.

2.8.1. Um exemplo

Considere 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 comumente encontrados num documento web, tais como:

  • uma tabela
  • uma imagem
  • um link

Image

Um documento HTML tem geralmente a seguinte forma:

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

Todo o documento está delimitado pelas tags <html>...</html>. É composto por duas partes:

  1. <head>...</head>: esta é a parte não exibível do documento. Fornece informações ao navegador que irá exibir o documento. Contém frequentemente as tags <title>...</title>, que definem o texto que aparecerá na barra de título do navegador. Pode também conter outras tags, nomeadamente as que definem as palavras-chave do documento, que são depois utilizadas pelos motores de busca. Esta secção pode ainda conter scripts, geralmente escritos em JavaScript ou VBScript, que serão executados pelo navegador.
  2. <body attributes>...</body>: Esta é a secção que será exibida pelo navegador. As tags HTML contidas nesta secção indicam ao navegador o layout visual «desejado» para o documento. Cada navegador interpreta estas tags à sua maneira. Como resultado, dois navegadores podem exibir o mesmo documento web de forma diferente. Este é geralmente um dos desafios enfrentados pelos web designers.

O código HTML para o 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>

Apenas os pontos que nos interessam foram destacados no código:

HTML
e exemplos de HTML
Título do documento
As tags <title></title>
as tags aparecerão na barra de título do navegador quando o documento for exibido
barra horizontal
<hr>: exibe uma linha horizontal
tabela
<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">cell(1,2)</td>: define uma célula cujo conteúdo será cell(1,2). Este conteúdo será centralizado verticalmente (valign="middle") e horizontalmente (align="center"). A célula terá uma largura de 150 píxeis (width="150")
imagem
<img border="0" src="/images/univ01.gif" width="80" height="95"> : define uma imagem sem borda (border="0"), 95 píxeis de altura (height="95"), 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 está localizada num documento web acessível através do URL http://localhost:81/html/balises.htm. Portanto, o navegador irá solicitar a URL http://localhost:81/images/univ01.gif para recuperar a imagem aqui referenciada.
link
<a href="http://istia.univ-angers.fr">aqui</a>: faz com que o texto «aqui» funcione como um link para a URL http://istia.univ-angers.fr.
fundo da página
<body background="/images/standard.jpg">: indica que a imagem a ser utilizada como fundo da página se encontra no 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 recuperar esta imagem de fundo.

Podemos ver neste exemplo simples que, para construir todo o documento, o navegador deve fazer três pedidos ao servidor:

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

O exemplo seguinte mostra um formulário web também criado com o FrontPage.

Image

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

<html>

  <head>
      <title>balises</title>
    <script language="JavaScript">
        function effacer(){
          alert("Vous avez cliqué sur le bouton Effacer");
      }//effacer
        </script>
  </head>

  <body background="/images/standard.jpg">

    <form method="POST" >

      <table border="0">
        <tr>
          <td>Etes-vous marié(e)</td>
          <td>
              <input type="radio" value="Oui" name="R1">Oui
              <input type="radio" name="R1" value="non" checked>Non
          </td>
        </tr>
        <tr>
          <td>Cases à cocher</td>
          <td>
              <input type="checkbox" name="C1" value="un">1
              <input type="checkbox" name="C2" value="deux" checked>2
              <input type="checkbox" name="C3" value="trois">3
          </td>
        </tr>
        <tr>
          <td>Champ de saisie</td>
          <td>
              <input type="text" name="txtSaisie" size="20" value="qqs mots">
          </td>
        </tr>
        <tr>
          <td>Mot de passe</td>
          <td>
              <input type="password" name="txtMdp" size="20" value="unMotDePasse">
          </td>
        </tr>
        <tr>
          <td>Boîte de saisie</td>
          <td>
               <textarea rows="2" name="areaSaisie" cols="20">
ligne1
ligne2
ligne3
</textarea>
          </td>
        </tr>
        <tr>
          <td>combo</td>
          <td>
              <select size="1" name="cmbValeurs">
                <option>choix1</option>
                <option selected>choix2</option>
                <option>choix3</option>
              </select>
          </td>
        </tr>
        <tr>
          <td>liste à choix simple</td>
          <td>
              <select size="3" name="lst1">
                <option selected>liste1</option>
                <option>liste2</option>
                <option>liste3</option>
                <option>liste4</option>
                <option>liste5</option>
              </select>
          </td>
        </tr>
        <tr>
          <td>liste à choix multiple</td>
          <td>
              <select size="3" name="lst2" multiple>
                <option>liste1</option>
                <option>liste2</option>
                <option selected>liste3</option>
                <option>liste4</option>
                <option>liste5</option>
              </select>
          </td>
        </tr>
        <tr>
          <td>bouton</td>
          <td>
              <input type="button" value="Effacer" name="cmdEffacer" onclick="effacer()">
          </td>
        </tr>
        <tr>
          <td>envoyer</td>
          <td>
              <input type="submit" value="Envoyer" name="cmdRenvoyer">
          </td>
        </tr>
        <tr>
          <td>rétablir</td>
          <td>
              <input type="reset" value="Rétablir" name="cmdRétablir">
          </td>
        </tr>
      </table>
      <input type="hidden" name="secret" value="uneValeur">

    </form>
  </body>
</html>

A associação visual entre <--> e a tag HTML é a seguinte:

Visual
Etiqueta HTML
form
<form method="POST" >
campo de entrada
<input type="text" name="txtInput" size="20" value="algumas palavras">
campo de entrada oculto
<input type="password" name="txtPassword" size="20" value="aPassword">
campo de entrada multilinha
<textarea rows="2" name="inputArea" cols="20">
linha1
linha2
linha3
</textarea>
botões de opção
<input type="radio" value="Sim" name="R1">Sim
<input type="radio" name="R1" value="No" checked>Não
caixas de seleção
<input type="checkbox" name="C1" value="one">1
<input type="checkbox" name="C2" value="dois" checked>2
<input type="checkbox" name="C3" value="três">3
Lista suspensa
<select size="1" name="cmbValues">
<option>opção1</option>
<option selected>opção2</option>
<option>opção3</option>
</select>
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>
lista de seleção múltipla
<select size="3" name="lst2" multiple>
<option>lista1</option>
<option>lista2</option>
<opção selecionada>list3</option>
<option>lista4</option>
<option>lista5</option>
</select>
botão de envio
<input type="submit" value="Enviar" name="cmdSubmit">
botão de reiniciar
<input type="reset" value="Redefinir" name="cmdReset">
botão
<input type="button" value="Limpar" name="cmdClear" onclick="clear()">

Vamos rever estes diferentes controlos.

2.8.1.1. O

formulário
<form method="POST" >
tag HTML
<form name="..." method="..." action="...">...</form>
atributos
name="exampleform": nome do formulário
method="..." : método utilizado pelo navegador para enviar os valores recolhidos no formulário para o servidor web
action="..." : URL para a qual os valores recolhidos no formulário serão enviados.
Um formulário web é delimitado pelas tags <form>...</form>. O formulário pode ter um nome (name="xx"). Isto aplica-se a todos os controlos encontrados dentro de um 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 informações introduzidas pelo utilizador através do teclado ou do rato e enviá-las para um URL de servidor web. Qual? Aquele referenciado no atributo action="URL". Se este atributo estiver em falta, as informações serão enviadas para o URL do documento no qual o formulário se encontra. Este seria o caso no exemplo acima. Até agora, sempre vimos o cliente web como «solicitando» informações de um servidor web, nunca como «fornecendo» informações a ele. Como é que um cliente web fornece informações (os dados contidos no formulário) a um servidor web? Voltaremos a este assunto em pormenor um pouco mais tarde. Pode utilizar dois métodos diferentes chamados POST e GET. O atributo method="método", em que método é GET ou POST, da tag <form> indica ao navegador qual o método a utilizar para enviar as informações recolhidas no formulário para a URL especificada 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 entrada

Image

Image

campo de entrada
<input type="text" name="txtInput" size="20" value="algumas palavras">
<input type="password" name="txtMdp" size="20" value="aPassword">
tag HTML
<input type="..." name="..." size=".." value="..">
A tag input existe para vários controlos. É o atributo type que distingue estes diferentes controlos uns dos outros.
atributos
type="text": especifica que este é um campo de entrada de texto
type="password": os caracteres no campo de entrada são substituídos por asteriscos (*). Esta é a única diferença em relação a um campo de entrada normal. Este tipo de controlo é adequado para introduzir palavras-passe.
size="20": número de caracteres visíveis no campo — não impede a introdução de mais caracteres
name="txtInput": nome do controlo
value="algumas palavras": texto que será exibido no campo de entrada.

2.8.1.3. Campo de entrada multilinha

Image

campo de entrada multilinha
<textarea rows="2" name="areaSaisie" cols="20">
linha1
linha2
linha 3
</textarea>
Tag HTML
<textarea ...>texto</textarea>
exibe um campo de entrada de texto multilinha com texto já inserido
atributos
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

botões de opção
<input type="radio" value="Sim" name="R1">Sim
<input type="radio" name="R1" value="no" checked>Não
Etiqueta HTML
<input type="radio" attribute2="value2" ....>texto
Exibe um botão de opção com texto ao lado.
atributos
name="radio": nome do controlo. Os botões de opção com o mesmo nome formam um grupo mutuamente exclusivo: apenas um deles pode ser selecionado.
value="valor": valor atribuído ao botão de opção. Não confunda este valor com o texto exibido ao lado do botão de opção. O texto serve apenas para fins de 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.5. Caixas de seleção

caixas de seleção
<input type="checkbox" name="C1" value="one">1
<input type="checkbox" name="C2" value="two" checked>2
<input type="checkbox" name="C3" value="three">3

Image

Etiqueta HTML
<input type="checkbox" attribute2="value2" ....>texto
exibe uma caixa de seleção com texto ao lado.
atributos
name="C1": nome do controlo. As caixas de seleção podem ou não ter o mesmo nome. As caixas de seleção com o mesmo nome formam um grupo de caixas de seleção relacionadas.
value="value": o valor atribuído à caixa de seleção. Não confunda este valor com o texto exibido ao lado do botão de opção. O texto serve apenas para fins de 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="cmbValues">
<option>opção1</option>
<option selected>opção2</option>
<option>opção3</option>
</select>

Image

Etiqueta HTML
<select size=".." name="..">
<option [selected]>...</option>
...
</select>
exibe o texto entre as tags <option>...</option> numa lista
atributos
name="cmbValeurs": nome do controlo.
size="1": número de itens visíveis da lista. size="1" torna a lista equivalente a uma caixa combinada.
selected: se esta palavra-chave estiver presente para um item da lista, esse item aparece selecionado na lista. No nosso exemplo acima, o item da lista choice2 aparece como o item selecionado na caixa combinada quando é exibido pela primeira vez.

2.8.1.7. Lista de seleção única

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>

Image

Etiqueta HTML
<select size=".." name="..">
<option [selected]>...</option>
...
</select>
exibe o texto entre as tags <option>...</option> numa lista
atributos
os mesmos que para a lista suspensa que exibe apenas um item. Este controlo difere da lista suspensa anterior apenas no seu atributo size>1.

2.8.1.8. Lista de seleção múltipla

lista de seleção única
<select size="3" name="lst2" multiple>
<option selected>list1</option>
<option>lista2</option>
<option selected>lista3</option>
<option>lista4</option>
<option>lista5</option>
</select>

Image

Tag HTML
<select size=".." name=".." multiple>
<option [selected]>...</option>
...
</select>
exibe o texto entre as tags <option>...</option> numa lista
atributos
multiple: permite que vários itens sejam selecionados da lista. No exemplo acima, os itens list1 e list3 estão ambos selecionados.

2.8.1.9. Botão

botão
<input type="button" value="Limpar" name="cmdClear" onclick="clear()">

Image

Etiqueta HTML
<input type="button" value="..." name="..." onclick="clear()" ....>
atributos
type="button": define um controlo de botão. Existem outros dois tipos de botões: submit e reset.
value="Clear": o texto exibido no botão
onclick="function()": permite definir uma função a ser executada quando o utilizador clica no botão. Esta função faz parte dos scripts definidos no documento web apresentado. A sintaxe acima é a sintaxe JavaScript. Se os scripts forem escritos em VBScript, escrever-se-ia onclick="function" sem os parênteses. A sintaxe permanece a mesma se for necessário passar parâmetros para a função: onclick="function(val1, val2,...)"
No nosso exemplo, clicar no botão Limpar chama a seguinte função de limpeza em JavaScript:
    <script language="JavaScript">
        function clear(){
          alert("Clicou no botão Limpar");
      }//clear
        </script>
A função clear exibe uma mensagem:

2.8.1.10. Botão Enviar

Botão Enviar
<input type="submit" value="Enviar" name="cmdSend">

Image

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

2.8.1.11. Botão Reiniciar

botão de reinicialização
<input type="reset" value="Redefinir" name="cmdReset">

Image

Tag HTML
<input type="reset" value="Redefinir" name="cmdReset">
atributos
type="reset": define o botão como um botão de reinicialização do formulário. Quando o utilizador clica neste botão, o navegador restaura o formulário para o estado em que foi recebido.
value="Reset": o texto exibido no botão

2.8.1.12. Campo oculto

campo oculto
<input type="hidden" name="secret" value="aValue">
tag HTML
<input type="hidden" name="..." value="...">
atributos
type="hidden": especifica que este é um campo oculto. Um campo oculto faz parte do formulário, mas não é apresentado ao utilizador. No entanto, se o utilizador solicitar ao seu navegador que apresente o código-fonte, verá a presença da tag <input type="hidden" value="..."> e, consequentemente, o valor do campo oculto.
value="aValue": valor do campo oculto.
Qual é a finalidade de um campo oculto? Permite que o servidor web retenha informações entre as solicitações de um cliente. Considere uma aplicação de compras online. O cliente compra um primeiro artigo art1 na quantidade q1 na primeira página de um catálogo e, em seguida, passa para uma nova página no catálogo. Para lembrar que o cliente comprou q1 artigos de art1, o servidor pode colocar estas duas informações num campo oculto no formulário web da nova página. Nesta nova página, o cliente compra q2 unidades de art2. Quando os dados deste segundo formulário forem enviados para o servidor, este não só receberá a informação (q2,art2), mas também (q1,art1), que também faz parte do formulário como um campo oculto que não pode ser modificado pelo utilizador. O servidor web colocará então as informações (q1,art1) e (q2,art2) num novo campo oculto e enviará uma nova página do catálogo. E assim por diante.

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

Mencionámos na lição anterior que o cliente web dispõe de dois métodos para enviar os valores de um formulário que apresentou para um servidor web: os métodos GET e POST. Vejamos um exemplo para perceber a diferença entre os dois métodos. Vamos revisitar o exemplo anterior e tratá-lo da seguinte forma:

  1. Um navegador solicita a URL do exemplo a um servidor web
  2. Assim que o formulário é obtido, preenchemo-lo
  3. Antes de enviar os valores do formulário para o servidor web clicando no botão «Submit», paramos o servidor web e substituímo-lo pelo servidor TCP genérico utilizado anteriormente. Lembre-se de que este servidor exibe no ecrã as linhas de texto que lhe são enviadas pelo cliente web. Desta forma, veremos exatamente o que o navegador está a enviar.

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á programado 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" >

Paramos o servidor web e iniciamos o nosso servidor TCP genérico 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 Enviar:

Image

Eis o que o servidor TCP genérico 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
<--

Está tudo 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

Podemos ver que isto é muito mais complexo do que aquilo com que nos deparámos até agora. Utiliza a sintaxe de URL GET HTTP/1.1, mas num formato específico: GET URL?param1=value1&param2=value2&... HTTP/1.1, em que os parâmetros são os nomes dos controlos do formulário web e os valores são os valores a eles associados. Vamos analisar isto mais de perto. Abaixo encontra-se uma tabela de três colunas:

  • Coluna 1: mostra a definição de um controlo HTML do exemplo
  • Coluna 2: mostra como este controlo aparece num navegador
  • Coluna 3: mostra o valor enviado ao servidor pelo navegador para o controlo da Coluna 1, na forma que assume 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="no" 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="one">1
<input type="checkbox" name="C2" value="two" checked>2
<input type="checkbox" name="C3" value="three">3
C1=um
C2=dois
- valores dos atributos value das caixas de seleção marcadas pelo utilizador
<input type="text" name="txtInput" size="20" value="algumas palavras">
txtInput=programação+web
- texto digitado pelo utilizador no campo de entrada. Os espaços foram substituídos pelo sinal +
<input type="password" name="txtMdp" size="20" value="aPassword">
txtPassword=thisIsSecret
- texto introduzido pelo utilizador no campo de entrada
<textarea rows="2" name="areaSaisie" cols="20">
linha1
linha2
linha3
</textarea>
campo de entrada=noções+básicas+de+programação+web%0D%0A
programação+web
- texto digitado pelo utilizador no campo de entrada. %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ção2</option>
<option>opção3</option>
</select>
cmbValues=option3
- valor selecionado 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=list3
- valor selecionado pelo utilizador na lista de seleção única
<select size="3" name="lst2" multiple>
<option selected>list1</option>
<option>lista2</option>
<option selected>lista3</option>
<option>lista4</option>
<option>lista5</option>
</select>
lst2=list1
lst2=lista3
- valores selecionados pelo utilizador a partir da lista de seleção múltipla
<input type="submit" value="Enviar" name="cmdSubmit">
 
cmdSubmit=Enviar
- atributos name e value do botão utilizado para enviar os dados do formulário para o servidor
<input type="hidden" name="secret" value="aValue">
 
secret=aValue
- atributo value do campo oculto

Vamos fazer o mesmo novamente, mas desta vez vamos deixar que o servidor web gere a resposta e ver qual é. A página devolvida pelo servidor web é a seguinte:

Image

É exatamente igual à que foi recebida inicialmente, antes de o formulário ter sido preenchido. Para compreender porquê, precisamos de analisar novamente o URL solicitado pelo navegador quando o utilizador clica no botão «Submit»:

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

O URL solicitado é /html/tags.htm. Também passamos os valores do formulário para este URL. Por enquanto, o URL /html/tags.htm, que é uma página estática, não utiliza estes valores. Portanto, o pedido GET anterior é equivalente a

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

e é por isso que o servidor nos enviou a página inicial novamente. Note que o navegador exibe o URL completo que foi solicitado:

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

Paramos o servidor web e iniciamos o servidor TCP genérico (que já vimos anteriormente, mas que foi ligeiramente modificado para este fim) 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 utilizando o botão Enviar:

Image

Eis o que o servidor TCP genérico 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á sabemos, observamos as seguintes alterações no pedido do navegador:

  1. O cabeçalho HTTP inicial já não é GET, mas sim POST. A sintaxe é POST HTTP/1.1 URL, em que URL é o URL solicitado pelo navegador. Ao mesmo tempo, POST significa que o navegador tem dados para enviar 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) que são codificados por URL. Esta codificação faz com que certos caracteres nos dados transmitidos sejam transformados para evitar que o servidor os interprete incorretamente. Assim, o espaço é substituído por +, a quebra de linha por %OD%OA, e assim por diante. Geralmente, todos os caracteres contidos nos dados que poderiam ser mal interpretados pelo servidor (&, +, %, etc.) são convertidos para %XX, onde XX é o seu código hexadecimal.
  3. A linha Content-Length: 210 indica ao servidor quantos caracteres o cliente enviará assim que os cabeçalhos HTTP estiverem completos, ou seja, após a linha em branco que sinaliza o fim dos cabeçalhos.
  4. Os dados (210 caracteres): R1=Yes&C1=one&C2=two&txtInput=web+programming&txtPassword=thisissecret&areaInput=the+basics+of+web%0D%0Aweb+programming&cmbValues=choice3&lst1=list3&lst2=list1&lst2=list3&cmdSubmit=Submit&secret=aValue

Note que os dados enviados via POST têm o mesmo formato que os dados enviados via GET.

Será que um método é melhor do que o outro? Vimos que, se os valores de um formulário fossem enviados pelo navegador utilizando o método GET, o navegador exibiria o URL solicitado na sua barra de endereços na forma URL?param1=val1&param2=val2&.... Isto pode ser visto como uma vantagem ou uma desvantagem:

  • uma vantagem se quiser permitir que o utilizador guarde esta URL parametrizada nos seus favoritos
  • uma desvantagem se não quiser que o utilizador tenha acesso a determinadas informações do formulário, tais como campos ocultos

A partir de agora, utilizaremos o método POST quase exclusivamente nos nossos formulários.

2.8.2.3. Recuperar valores de um formulário Web

Uma página estática solicitada por um cliente que também envia parâmetros via POST ou GET não pode recuperá-los de forma alguma. Apenas um programa pode fazer isso, e é o programa que irá então gerar uma resposta para o cliente — uma resposta que será dinâmica e geralmente baseada nos parâmetros recebidos. Este é o domínio da programação web, um tópico que abordaremos com mais detalhe no próximo capítulo, com uma introdução às tecnologias de programação web Java: servlets e páginas JSP.