Tutorial
Tutorial
18 de agosto de 2006
O modelo clássico de aplicação web trabalha assim: A maioria das ações do usuário
na interface dispara uma solicitação HTTP para o servidor web. O servidor processa algo
recuperando dados, mastigando números, conversando com vários sistemas legados e
então retorna uma página HTML para o cliente. É um modelo adaptado do uso original
da web como um agente de hipertexto, porém o que faz a web boa para hipertexto não
necessariamente faz ela boa para aplicações de software.
Esta aproximação possui muito dos sentidos técnicos, mas não faz tudo que um usuário
experiente poderia fazer. Enquanto o servidor está fazendo seu trabalho, o que o usuário
estará fazendo? O que é certo, esperando. E a cada etapa em uma tarefa, o usuário
aguarda mais uma vez.
1
Obviamente, se nós estivéssemos projetando a web do nada para aplicações, não fa-
ríamos com que os usuários esperassem em vão. Uma vez que a interface está carregada,
por que a interação do usuário deveria parar a cada vez que a aplicação precisasse de algo
do servidor? Na realidade, por que o usuário deveria ver a aplicação ir ao servidor toda
vez?
A maior vantagem das aplicações AJAX é que elas rodam no próprio navegador web.
Então, para estar hábil a executar aplicações AJAX, bastar possuir algum dos navegadores
modernos, ou seja, lançados após 2001, são eles: Mozilla Firefox, Internet Explorer 5+,
Opera, Konqueror e Safari.
2 A Classe Assíncrona
Para se fazer um pedido HTTP ao servidor usando Javascript, você precisa de um objeto
que disponibiliza essa funcionalidade. Tal classe foi primeiro introduzida no Internet Ex-
2
plorer sob a forma de um objeto ActiveX chamado XMLHTTP, então, o Mozilla, o Safari
e outros browsers seguiram-se, implementando uma classe de nome XMLHttpRequest que
suportava os métodos e as propriedades do objeto ActiveX original da Microsoft.
O código abaixo mostra a forma genérica de instanciar um objeto que proverá os
mecanismos para pedidos assíncronos.
Código 1: 'ajaxInit.js'
1 function ajaxInit () {
2
3 var xmlhttp ;
4
5 try {
6 xmlhttp = new XMLHttpRequest ( ) ;
7 } catch ( ee ) {
8 try {
9 xmlhttp = new ActiveXObject ( " Msxml2 . XMLHTTP " ) ;
10 } catch ( e ) {
11 try {
12 xmlhttp = new ActiveXObject ( " Microsoft . XMLHTTP " ) ;
13 } c a t c h (E) {
14 xmlhttp = f a l s e ;
15 }
16 }
17 }
18
19 return xmlhttp ;
20 }
2.1 Atributos
Segue abaixo alguns dos atributos do objeto de conexão assíncrona.
readyState : Código que diz o status da solicitação assíncrona, ele varia de 0 até 5
• 0 (uninitialized);
• 1 (a carregar);
• 2 (carregado);
• 3 (interativo);
• 4 (completo).
status : Status do retorno do HTML, são os códigos padrões do HTML 200 ok, 400
no found
responseText : Retorna a cadeia de caracteres que o servidor enviou.
responseXml : Retorna o XML o servidor enviou.
onreadystatechange : Dene qual função será chamada para fazer a manipulação
dos dados assim que houver um retorno.
http_request.onreadystatechange = nameOfTheFunction;
3
Vamos ver o que é que esta função deve fazer. Primeiro, a função precisa de vericar o
estado do pedido, se o estado possui o valor 4, isso signica que a totalidade da resposta
do servidor foi recebida e que pode continuar a processá-la à vontade, a próxima coisa a
vericar é o código do estado da resposta HTTP do servidor. Para os nossos objetivos só
estamos interessados na resposta 200 OK.
if (http_request.readyState == 4) {
if (http_request.status == 200) {
// deu certo
} else {}
}
2.2 Métodos
Segue abaixo alguns dos métodos do objeto de conexão assíncrona.
open(mode, url, boolean)
• mode: Tipo da requisição, GET ou POST
4
14 i f ( a j a x . s t a t u s == 2 0 0 ) {
15 document . getElementById ( " texto " ) . innerHTML = a j a x . r e s p o n s e T e x t ;
16 }
17 }
18 }
19 }
20 a j a x . send ( n u l l ) ;
21 }
22 </ s c r i p t >
23 </head>
24 <body>
25 <d i v i d=" texto "></div>
26 <i n p u t type=" button " v a l u e=" Carregar " o n C l i c k=" carregar () "/>
27 </body>
28 </html>
Na linha 8 ocorre a chamada para a função ajaxInit() que esta dentro do arquivo
referenciado na linha 5. A linha 9 getElementByid('texto') 1 e innerHTML2 inserem o
texto Carregando dentro do DIV com o id igual a texto.
Nas linhas 11, 12 e 13 são vericados o status do pedido, e do retorno e efetiva inserção
do conteúdo do arquivo texto.txt no DIV, respectivamente.
Neste primeiro exemplo não houve nenhum processamento por parte de uma linguagem
de programação no servidor, porém no mundo real geralmente uma chamada no modo
assíncrono se comunica com um script (PHP, JSP, ASP, Ruby, CGI, PERL ...), que faz
um processamento sobre os dados a ele enviados e por m retorna o resultado, nosso
próximo exemplo mostrará exatamente isto.
5
15 a j a x . open ( ' GET ' , u r l , t r u e ) ;
16 a j a x . send ( n u l l ) ;
17 }
18 }
19
20 function resultado () {
21 i f ( a j a x . r e a d y S t a t e == 4 ) {
22 i f ( a j a x . s t a t u s == 2 0 0 ) {
23 document . getElementById ( " resultado " ) . innerHTML = a j a x . r e s p o n s e T e x t ;
24 }
25 }
26 }
27 </ s c r i p t >
28 </head>
29 <body>
30 <form name=" calculadora ">
31 <i n p u t type=" text " name=" v1 " i d=" v1 " s i z e="3"/> + <i n p u t type=" text " name=" v2 "
i d=" v2 " s i z e="3 "/> =
32 <l a b e l i d=" resultado "></l a b e l > <br/>
33 <i n p u t type=" button " v a l u e=" Carregar " o n C l i c k=" calcular () "/>
34 </form>
35 </body>
36 </html>
• É uma propriedade desenvolvida pela Microsoft, por esta razão proprietária, porém
a maior parte dos navegadores incorporou-a.
• Por não ser padrão esta sendo abolida das novas versões destes navegadores
Os próximos dois exemplo são idênticos, diferenciando apena a forma como os dados
são passados do servidor para o cliente, o primeiro usando texto normal e o outro uma
string no formato JSON, usando então o DOM para exibir o resultado da requisição.
3 Propiedade de alguns objetos em Javascript que retorna o conteúdo do mesmo
6
5 Exemplo 3 Preenchimento um SELECT a partir de
outro SELECT
Um exemplo clássico do preenchimento de um SELECT a partir de outro é a escolha das
cidades de um determinado estado. Este recurso é uma das maiores 'pedras no sapato'
dos programadores de sistema web, pois quando o usuário seleciona o estado toda a página
deve ser recarregada, inclusive os valores dos demais campos já preenchidos, para que o
SELECT com as cidades seja exibido.
Com AJAX esta tarefa ca bem mais fácil pois basta que seja feita uma consulta das
cidades do estado que esta no primeiro SELECT e inserir as cidades no segundo SELECT.
7
43 </html>
O arquivo Cidades.php gera os elementos options que serão inseridos dentro do SE-
LECT das cidades. Esta abordagem não é muito inteligente pois a quantidade de infor-
mação transmitidas do servidor para o cliente em sua maioria foi desnecessária. Da cidade
apenas o código e o nome deveriam ser transmitidos, as demais informações são repetidas
e podem ser geradas pelo navegador.
Na linha 31 do código fonte 5 é feita a vericação se um dos elementos do SELECT
estado foi selecionado, se sim então envie o valor para a função selecionaCidade.
O código fonte 6 a variável estado é recebida e de acordo com ela é passado ao nave-
gador as opções do SELECT cidade.
8
razão JSON é tipicamente usado em ambientes onde o tamanho do uxo de dados entre o
cliente e o servidor é de supra importância (daí seu uso por Google, Yahoo, etc., os quais
servem milhões de usuários), onde a fonte dos dados pode ser explicitamente conável, e
onde a perda dos recursos de processamento XSLT no lado cliente para manipulação de
dados ou geração da interface, não é uma consideração.
Enquanto JSON é freqüentemente posicionado "em confronto"com XML, não é inco-
mum ver tanto JSON como XML sendo usados na mesma aplicação. Por exemplo, uma
aplicação no lado cliente a qual integra dados do Google Maps com dados atmosféricos
através de SOAP, requer suporte para ambos formatos de dados.
{
'cidades':[
{'cdg':'1','nm':'Tupãssi'},
{'cdg':'2','nm':'Toledo'},
{'cdg':'3','nm':'Cascavel'},
{'cdg':'4','nm':'Pato Branco'}
]
}
Usando a função eval 4 do Javascript podemos transformar esta string em uma estru-
tura de objetos facilmente manipuláveis.
Se usarmos a função eval no retorno das cidades poderiamos por exemplo acessar o
código da cidade de Pato Branco através do seguinte comando:
json = eval("("+ajax.responseText+")");
json.cidades[3].cdg;
Na primeira linha é aplicada a função eval e seu resultado é armazenado na variável
Json, na linha 2 é acessado o atributo cidades, que é um vetor, na posição 3 no atributo
cdg.
Para um exemplo completo veja os códigos abaixo.
4 Introduzidana especicação 1.0 do Javascript esta função interpreta uma string como uma expressão,
eval("fred=999; wilma=777; document.write(fred + wilma);") retorna 1776
9
Código 7: 'Cidades HTML'
1 <!DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd ">
3 <html xmlns=" http :// www . w3 . org /1999/ xhtml " xml : l a n g="pt - br "
4 l a n g="pt - br ">
5 <head>
6 < t i t l e >Exemplo 3 − E s c o l h a a Cidade </ t i t l e >
7 < s c r i p t type=" text / javascript " s r c=" ajaxInit . js "></s c r i p t >
8 < s c r i p t type=" text / javascript ">
9
10 function selecionaCidadeJson ( estado ) {
11 ajax = a j a x I n i t () ;
12 i f ( ajax ) {
13 ajax . onreadystatechange = escreveCidadesJson ;
14 u r l = ' http ://200.201.81.38/ anselmo / ciclo / cidadesJson . php ? estado = '+e s t a d o ;
15 a j a x . open ( ' GET ' , u r l , t r u e ) ;
16 a j a x . send ( n u l l ) ;
17 }
18 }
19
20 function escreveCidadesJson () {
21 i f ( a j a x . r e a d y S t a t e == 4 ) {
22 i f ( a j a x . s t a t u s == 2 0 0 ) {
23 var x = 0 ;
24 var j s o n = e v a l ( "("+a j a x . r e s p o n s e T e x t+")" ) ;
25
26 l i m p a r D e s t i n o ( " cidade2 " ) ;
27
28 for ( x=0;x<=j s o n . c i d a d e s . l e n g t h ; x++){
29
30 o p t i o n = document . c r e a t e E l e m e n t ( " option " ) ;
31
32 o p t i o n . s e t A t t r i b u t e ( " value " , j s o n . c i d a d e s [ x ] . cdg ) ;
33
34 o p t i o n . appendChild ( document . createTextNode ( j s o n . c i d a d e s [ x ] . nm) ) ;
35
36 document . getElementById ( document . createTextNode ( j s o n . c i d a d e s [ x ] . nm) ) ;
37
38 document . getElementById ( " cidade2 " ) . appendChild ( o p t i o n ) ;
39 }
40 }
41 }
42 }
43
44 /∗
45 Remove t o d o s os e l e m e n t o s f i l h o s de um elemento
46 ∗/
47 function limparDestino ( destino ) {
48 o b j = document . getElementById ( d e s t i n o ) ;
49 while ( o b j . f i r s t C h i l d )
50 o b j . removeChild ( o b j . f i r s t C h i l d ) ;
51 }
52
53 </ s c r i p t >
54 </head>
55 <body>
56 <form name=" selecioneCidade ">
57 <l a b e l for=" estado " a c c e s s k e y="e"><u>E</u>s t a d o :</ l a b e l >
58 < s e l e c t name=" estado " i d=" estado " onChange=" if ( this . options [ this . selectedIndex
]. value ) { selecionaCidadeJson ( this . options [ this . selectedIndex ]. value )} ">
59 <o p t i o n v a l u e=" -">−−−</o p t i o n >
60 <o p t i o n v a l u e=" pr ">PR</o p t i o n >
61 <o p t i o n v a l u e=" sp ">SP</o p t i o n >
62 </ s e l e c t ><br/>
63
10
64 <l a b e l for=" cidade " a c c e s s k e y="c"><u>C</u>i d a d e :</ l a b e l >
65 < s e l e c t name=" cidade " i d=" cidade2 ">
66 </ s e l e c t >
67 </form>
68 </body>
69 </html>
Revisando o Código 8 podemos ver que a linha 2 chama a função header, nela é passado
o comando charset=iso88591, isto é muito importante pois diz a codicação do texto que
esta sendo retornado, evitando assim que o navegador do usuário exiba de forma incorreta
os acentos e outros caracteres especiais.
Com os exemplos acima pudemos ter uma boa noção de como utilizar o ajax em nossas
aplicações web, mas, queremos coisas mais dinâmicas e com efeitos por isso vamos fazer
um pequeno Google Sugest
6 Sugerindo um Conteúdo
Nosso próximo exemplo consistirá em um campo de texto que a cada tecla pressionada irá
ao servidor e trará uma lista de palavras que comecem com o que já foi escrito. Isto será
exibido em uma DIV. Quando clicarmos em uma das palavras que vieram do servidor a
DIV irá sumir e o texto irá para dentro da caixa de texto.
Este sistema é utilizado por exemplo no serviço de e-mail do Yahoo, nele, quando
digita-se o nome do contato ele já vai ltrando os que começam com as letras já digitadas.
Código 9: 'Auto Completar HTML'
1 <!DOCTYPE HTML PUBLIC " -// W3C // DTD HTML 3.2 Final // EN ">
2 <html>
3 <head>
4 < t i t l e >Auto Completar </ t i t l e >
5 < s c r i p t type=" text / javascript " s r c=" ajaxInit . js "></s c r i p t >
6 < s c r i p t type=" text / javascript ">
7 function sugerir ( s ) {
11
8 ajax = a j a x I n i t () ;
9 document . getElementById ( " resultado " ) . innerHTML = " Calculando ... " ;
10 i f ( ajax ) {
11 ajax . onreadystatechange = resultado ;
12 u r l = ' http ://200.201.81.38/ anselmo / ciclo / autoCompletar . php ?s= '+s ;
13 a j a x . open ( ' GET ' , u r l , t r u e ) ;
14 a j a x . send ( n u l l ) ;
15 }
16 }
17
18 function resultado () {
19 i f ( a j a x . r e a d y S t a t e == 4 ) {
20 i f ( a j a x . s t a t u s == 2 0 0 ) {
21 j s o n = e v a l ( "("+a j a x . r e s p o n s e T e x t+") " ) ;
22 var x = 0 ;
23 l i m p a r D e s t i n o ( " resultado " ) ;
24 document . getElementById ( ' resultado ' ) . s t y l e . v i s i b i l i t y =' visible ' ;
25 for ( x=0; x < j s o n . p a l . l e n g t h ; x++) {
26 P = document . c r e a t e E l e m e n t ( "p" ) ;
27 P . appendChild ( document . createTextNode ( j s o n . p a l [ x ] ) ) ;
28 P . s e t A t t r i b u t e ( " onClick " , " document . getElementById (' pal '). value ='"+
j s o n . p a l [ x]+" '; document .
getElementById ( ' resultado '). style . visibility =' hidden '" ) ;
29 document . getElementById ( " resultado " ) . appendChild (P) ;
30 }
31 }
32 }
33 }
34
35 /∗
36 Remove t o d o s os e l e m e n t o s f i l h o s de um elemento
37 ∗/
38 function limparDestino ( destino ) {
39 o b j = document . getElementById ( d e s t i n o ) ;
40 while ( o b j . f i r s t C h i l d )
41 o b j . removeChild ( o b j . f i r s t C h i l d ) ;
42 }
43 </ s c r i p t >
44 < s t y l e type=" text / css ">
45 #r e s u l t a d o {
46 background − c o l o r : #e 5 e 5 e 5 ;
47 border : 1px s o l i d #000;
48 width : 150 px ;
49 padding : 0px ;
50 margin : 0px ;
51 position : relative ;
52 margin − l e f t : 45 px ;
53 margin −top : 0px ;
54 }
55 p {
56 l i n e −h e i g h t : 15 px ;
57 margin : 0px ;
58 font : 18 px " Arial " , sans − s e r i f ;
59 padding : 5px ;
60 }
61 p : hover {
62 background − c o l o r : #cdcdcd ;
63 cursor : pointer ;
64 }
65 </ s t y l e >
66 </head>
67 <body>
68 <form name=" auto ">
69 <l a b e l for=" pal " a c c e s s k e y=" pal ">Palavra </ l a b e l >
70 <i n p u t type=" text " i d=" pal " name=" pal " onKeyUp=" sugerir ( document . getElementById
12
(' pal '). value )"/>
71 <d i v i d=" resultado " s t y l e=" visibility : hidden "></div>
72 </form>
73 </body>
74 </html>
13
1 <?php
2 # FileName=" Connection_php_mysql . htm "
3 # Type=" MYSQL "
4 # HTTP=" true "
5 $hostname_conexao = " localhost " ;
6 $database_conexao = " test " ;
7 $username_conexao = " aluno " ;
8 $password_conexao = " aluno " ;
9 $conexao = mysql_pconnect ( $hostname_conexao , $username_conexao , $password_conexao ) o r d i e
( mysql_error ( ) ) ;
10 mysql_select_db ( $database_conexao , $conexao ) ;
11 ?>
O código 11 cria uma conexão com o banco de dados, a linha 9 conecta com o servidor
usando o usuário e senha e a linha 10 inicia o uso do banco de dados text.
O código 12 faz a pesquisa dos municípios no banco de dados, na linha 2 é incluída o
arquivo que faz a conexão, na linha 4 a variável $search recebe a palavra que foi digitada
na caixa de texto, na linha 13 o comando str_replace 7 foi utilizado para evitar problemas
com palavras que por ventura contenham aspas simples como por exemplo d'agua
, se este
tratamento não for feito na hora de chamar a função eval ocorreria um erro.
• Torna possível utilizar uma aplicação baseada na web com recurso e funcionalidades
parecidos com os que possuímos hoje em nossos sistemas Desktop. Isto torna o uso
dos aplicativos web realmente usáveis;
• Como a modicação das informações da tela são parciais uma grande quantidade
de informações deixa de trafegar inutimente pela rede;
7 Substitui todas as ocorrências da string procurada na string de retorno
14
• O servidor que roda a aplicação ca menor carregado pois existe uma divisão de
tarefas com o cliente;
• AJAX não é uma tecnologia por isto não é necessário pagar para a utilizar.
Porém como já dizia o poeta "nem tudo são ores ", temos que:
• AJAX não é a solução milagrosa para todos os males e se usado de forma inadequada
pode piorar uma situação que já era feia;
• Os Navegadores usam diferentes métodos por isso temos que estar atentos quanto a
eles para não impossibilitar o uso de nossos sistemas por tais navegadores;
• Como existe uma divisão de processamente entre o cliente e o servidor, temos que
minimizar este processamento pois os Navegador em geral não suporta uma carga
muito pesada de scripts ;
• Os botão voltar, avança e histórico não funcionam muito bem com AJAX.
Referências
[1] Erko Bridee de Almeida Cabrera. AJAX Visão Conceitual. Portal Java, 2005.
15
• DHTML
http://www.quirksmode.org/js/cross_dhtml.html
• Exemplos em Ajax
http://www.japs.etc.br/ajax/
16