AJAX AJAX é acrônimo de Asynchronous JavaScript And XML. É um tipo de programação que se tornou popular in 2005 pela Google (com Google Suggest). AJAX não é uma nova linguagem de programação, mas uma nova forma de utilizar os padrões existentes. Com o AJAX se pode criar aplicações WEB melhores, mais rápidos e mais amigáveis. AJAX é baseado em JavaScript e requisições HTTP. Com AJAX, o JavaScript se comunica diretamente com o servidor utilizando o objeto XMLHttpRequest do JavaScript. Com este objeto se pode trocar dados com um servidor WEB sem a necessidade de recarregar a página. AJAX utiliza a transferência de dados assíncrona entre o navegador e o servidor WEB, permitindo que as páginas WEB façam pequenas requisições ao servidor WEB no lugar de uma página inteira. Esta tecnologia independe do servidor WEB. AJAX é baseado nos seguintes padrões WEB: JavaScript, XML, HTML, CSS. Em um código JavaScript tradicional, se desejar receber qualquer informação do banco de dados ou um arquivo do servidor, ou enviar uma informação do usuário para um servidor, ter-se-á criar um formulário HTML e enviar por GET ou POST dados para o servidor. O usuário terá que clicar no botão SUBMIT para enviar e receber as informações, esperar que o servidor para responder e então uma nova página será carregada com os resultados. Porque o servidor retorna uma nova página cada vez que o usuário submete uma entrada, as aplicações web são lentas e menos amigáveis. Para uma aplicação tradicional, uma página pode fazer uma requisição para, e receber uma resposta do servidor WEB sem a necessidade de recarregar a página. O usuário ficará na mesma página e não notará que o script requisitou páginas, ou enviou dados para o servidor em background. Objeto XMLHttpRequest Utilizando o objeto XMLHttpRequest, o programador web pode atualizar uma página com dados do servidor sem necessidade de recarregar a página. O Google em http://www.google.com/webhp?complete=1&hl=en fez com que AJAX se tornasse popular. Google Suggest esta utilizando objeto XMLHttpRequiest para criar uma interface web dinâmica, quando o usuário inicia digitando na caixa de pesquisa, um JavaScript envia as letras para o servidor e o servidor retorna uma lista de sugestões. O objeto XMLHttpRequest é suportado por Internet Explorer 5 ou superior, Safári 1.2, Mozilla 1.0 / Firefox, Opera 8+, and Nestscape 7. Primeira aplicação AJAX Primeiro, será criado um formulário padrão HTML com dois campos: nome e hora. O campo nome será preenchido pelo usuário e o campo hora será preenchido utilizando-se AJAX. O arquivo HTML terá o nome “testeAjax.html”, e seu conteúdo será: <html> <body> <form name="myForm"> Name: <input type="text" name="username" /> Time: <input type="text" name="time" /> </form> </body> </html> Destaca-se que o formulário não possui o botão Submit. Suporte AJAX do navegador A chave do AJAX é o objeto XMLHttpRequest. Navegadores diferentes utilizam métodos diferentes para criar o objeto XMLHttpRequest Internet Explorer utiliza um ActiveXObject, enquanto que outros navegadores utilizam um objeto JavaScript chamado XMLHttpRequest. Para criar este objeto e trabalhar com navegadores diferentes, será utilizado o comando “try and catch”. <html> <body> <script type="text/javascript"> function ajaxFunction() { var xmlHttp; try { // Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("Seu navegador não suporta AJAX!"); return false; } } } } </script> <form name="myForm"> Nome: <input type="text" name="nome" /> Time: <input type="text" name="time" /> </form> </body> </html> Primeiro cria-se uma variável xmlHttp para manter o objeto XMLHttpRequest. Então tenta-se criar o objeto com XMLHttp=new XMLHttpRequest(). Isto serve para os navegadores Firefox, Opera e Safári. Se falhar tenta-se com xmlHttp=new ActiveXObject("Msxml2.XMLHTTP") que serve para o Internet Explorer 6.0+, se também falhar, tentar xmlHttp=new ActiveXObject("Microsoft.XMLHTTP") que serve para o Internet Explorer 5.5+. Se nenhum dos três métodos funcionarem, o usuário possui um navegador muito desatualizado deverá ser avisado que não suporta AJAX. A propriedade onreadystatechange Depois de uma requisição para o servidor, precisa-se uma função que possa receber o dado que é retornado pelo servidor. A propriedade onreadystatechange armazena a função que processará a resposta do servidor. O código abaixo define uma função vazia e inicializa a propriedade onreadystatechange ao mesmo tempo. xmlHttp.onreadystatechange=function() { // Deve-se escrever um código } A propriedade readyState A propriedade readyState carrega a situação (status) da reposta do servidor (server’s reponse). Cada vez que muda o valor de readyState, a função onreadystatechange será executada. Tabela de possíveis valores para a propriedade de onreadystatechange. Valor 0 1 2 3 4 Descrição A requisição A requisição A requisição A requisição A requisição não foi inicializada foi configurada. foi enviada esta sendo processada esta completa No exemplo abaixo, apresenta-se um teste (if) na função onreadystatechange para testar se a resposta esta completa, ou seja, que o dado foi recebido. xmlHttp.onreadystatechange=function() { if(xmlHttp.readyState==4) { // Recebido dos dados do servidor. } } A propriedade responseText O dado enviado de volta do servidor pode ser recuperado com a propriedade responseText. No exemplo será colocado a hora no campo de entrada na propriedade responseText. xmlHttp.onreadystatechange=function() { if(xmlHttp.readyState==4) { document.myForm.time.value=xmlHttp.responseText; } } Enviando uma requisição ao servidor Para enviar uma requisição ao servidor utiliza-se o método open() e o método send(). O método open() requer três argumentos. O primeiro argumento define qual método utilizar quando estiver enviando a requisição (GET ou POST). O segundo argumento especifica a URL do script no servidor. O terceiro argumento especifica que a requisição deve ser manipulada assincronamente. O método send() envia a requisição para o servidor. Se assumir que os arquivos HTML e PHP estão na mesma pasta, o código pode ficar: xmlHttp.open("GET","time.asp",true); xmlHttp.send(null); A função AJAX será executada quando o usuário digita algo no campo nome. O arquivo testeAjax.html agora fica parecido com o seguinte código: <html> <body> <script type="text/javascript"> function ajaxFunction() { var xmlHttp; try { // Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("Seu navegador não suporta AJAX!"); return false; } } } xmlHttp.onreadystatechange=function() { if(xmlHttp.readyState==4) { document.myForm.time.value=xmlHttp.responseText; } } xmlHttp.open("GET","hora.php",true); xmlHttp.send(null); } </script> <form name="myForm"> Nome: <input type="text" onkeyup="ajaxFunction();" name="nome" /> Hora: <input type="text" name="time" /> </form> </body> </html> O código baixo apresenta a hora do servidor e deve ser gravado com o nome hora.php. A propriedade responseText armazenará a data que retorna do servidor. <? $d = getdate(); print str_pad($d['hours'],2,"0", STR_PAD_LEFT) .':'.str_pad($d['minutes'],2,"0",STR_PAD_LEFT) .':'.str_pad($d['seconds'],2,"0", STR_PAD_LEFT); ?> Abaixo se apresenta o resultado da execução dos scripts apresentados até o momento. A cada letra digitada é apresentado a hora do sistema sem a necessidade de recarregar a página. Exemplo XML com AJAX AJAX pode ser utilizado para uma comunicação interativa com arquivo XML. O código da página HTML abaixo apresenta uma lista de nomes que conforme a escolha apresenta os detalhes em uma área especial. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <html> <head> <script src="selectcd.js"></script> </head> <body> <form> Select a CD: <select name="cds" onchange="showCD(this.value)"> <option value="Bob Dylan">Bob Dylan</option> <option value="Bonnie Tyler">Bonnie Tyler</option> <option value="Dolly Parton">Dolly Parton</option> </select> </form> <p> <div id="txtHint"><b>A informação do CD será apresenta aqui.</b></div> </p> </body> </html> Na linha 15 existe um div denominado txtHint que é utilizado como um repositório das informações recuperadas do servidor WEB. Quando o usuário seleciona um dado, a função denominada showCD é executada. A execução da função é ativada pele evento onchange. O código JavaScript é armazenado no arquivo ‘selectcd.js’: var xmlHttp function showCD(str) { xmlHttp=GetXmlHttpObject(); if (xmlHttp==null) { alert ("Your browser does not support AJAX!"); return; } var url="getcd.php"; url=url+"?q="+str; url=url+"&sid="+Math.random(); xmlHttp.onreadystatechange=stateChanged; xmlHttp.open("GET",url,true); xmlHttp.send(null); } function stateChanged() { if (xmlHttp.readyState==4) { document.getElementById("txtHint").innerHTML=xmlHttp.responseText; } } function GetXmlHttpObject() { var xmlHttp=null; try { // Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } } return xmlHttp; } A função showCD() é executada quando usuário selecionar um item da caixa de seleção. 1. Chama a função GetXmlHttpObject para criar um objeto XMLHTTP. 2. Define o URL (nome do arquivo) para ser enviado para o servidor. 3. Adiciona um parâmetro (q) para a URL com o conteúdo do campo de entrada. 4. Adiciona um número randômico para prevenir que o servidor utilize um arquivo em cachê. 5. Chama a função stateChanged() quando um mudança é disparada. 6. Abre o objeto XMLHTTP com a URL dada. 7. Envia um requisição http para o servidor. A página PHP A página chamada pelo JavaScript é um arquivo PHP denominado “getcd.php”. A página abaixo escrita em PHP 5 utiliza a biblioteca XMLDOM para carregar um documento XML. <?php $q=$_GET["q"]; $xmlDoc = new DOMDocument(); $xmlDoc->load("cd_catalog.xml"); $x=$xmlDoc->getElementsByTagName('ARTIST'); for ($i=0; $i<=$x->length-1; $i++) { //Process only element nodes if ($x->item($i)->nodeType==1) { if ($x->item($i)->childNodes->item(0)->nodeValue == $q) { $y=($x->item($i)->parentNode); } } } $cd=($y->childNodes); for ($i=0;$i<$cd->length;$i++) { //Process only element nodes if ($cd->item($i)->nodeType==1) { echo($cd->item($i)->nodeName); echo(": "); echo($cd->item($i)->childNodes->item(0)->nodeValue); echo("<br />"); } } ?> Quando a consulta é enviada do JavaScript para o PHP ocorre: PHP cria um objeto XMLDOM do arquivo “cd_catalog.xml”. Todos os elementos (nodetypes=1) (Artistas) entram em um laço para encontrar um nome que seja igual ao nome enviado do JavaScript. O CD contendo o nome do artista é encontrado. A informação do álbum é enviada para o txtHint. Documento XML denominado “cd_catalog.xml”. <?xml version="1.0" encoding="ISO-8859-1"?> <!-- Edited with XML Spy v2007 (http://www.altova.com) --> <CATALOG> <CD> <TITLE>Empire Burlesque</TITLE> <ARTIST>Bob Dylan</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Columbia</COMPANY> <PRICE>10.90</PRICE> <YEAR>1985</YEAR> </CD> <CD> <TITLE>Hide your heart</TITLE> <ARTIST>Bonnie Tyler</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>CBS Records</COMPANY> <PRICE>9.90</PRICE> <YEAR>1988</YEAR> </CD> <CD> <TITLE>Greatest Hits</TITLE> <ARTIST>Dolly Parton</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>RCA</COMPANY> <PRICE>9.90</PRICE> <YEAR>1982</YEAR> </CD> </CATALOG> Exemplo AJAX para Select Box gerado com JAVA AJAX pode ser utilizado para requisitar um trecho de código para ser inserido na página HTML. O código da página HTML abaixo apresenta uma lista de estados que conforme a escolha apresenta as cidades do estado selecionado. <html> <body> <script type="text/javascript"> var xmlHttp; function GetXmlHttpObject(){ var xmlHttp=null; try{ xmlHttp=new XMLHttpRequest();// Firefox e similares }catch (e){// Internet Explorer try{ xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); }catch (e){ xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } } //catch IE return xmlHttp; } //function GetXmlHttpObject() function buscaMunJs(str){ xmlHttp=GetXmlHttpObject() var url="http://10.68.15.67:8080/modulos/BuscaMunicipio"; url=url+"?q="+str; url=url+"&sid="+Math.random(); xmlHttp.onreadystatechange=stateChanged; xmlHttp.open("GET",url,true); xmlHttp.send(null); } // function BuscaMunJs(str) function stateChanged(){ if (xmlHttp.readyState==4){ document.getElementById("txtHint").innerHTML=xmlHttp.responseText; } // if } // function stateChanged() </script> <table> <tr> <td>UF</td> <td> <select name='p_uf' onchange='buscaMunJs(this.value)'> <option value='0'>Escolher</option> <option value='12' >AC</option> <option value='27' >AL</option> (…) <option value='17' >TO</option> </select> </td> </tr> <tr> <td>Município</td><td> <span id="txtHint"></span></td> </tr> </table> </body> </html> Vale notar agora que o campo que será atualizado agora é <span> ao invés de <div>, mas o javascript de chamada da url é praticamente idêntico, então o que muda é a atribuição da resposta ao elemento HTML (nesse caso o “txtHint”). Arquivo JAVA utilizado para gerar o componente Select Segue trecho do Servlet (JAVA) que consulta um banco de dados e, baseado no parâmetro estado (q) retorna um select box com as cidades como opções. protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String uf = request.getParameter("q"); (…)//consiste parametro out.println("<select name='p_ibge_ajax' onchange='preencheIBGE(this.value)'>"); out.println("<option value='0'>Escolher</option>"); (…)//inicializa Banco de Dados List estados = bdSession.createSQLQuery("select m.ibge, m.nome from mapas.shp_munic m where trunc(m.ibge/10000) = " + uf + " order by nome").list(); Iterator estados_iter = estados.iterator(); while(estados_iter.hasNext()){ Object[] municipio = (Object[])estados_iter.next(); out.println("<option value='" + (Integer) municipio[0] + "'>" + (String) municipio[1] + "</option>"); } (…)//finaliza conexão c/ Banco de Dados out.println("</select>"); out.close(); } A resposta do Servlet é o código fonte de um componente Select contendo as cidades do estado recebido como parâmetro. Esse conteúdo é visualizado no navegador no lugar do span do HTML, porém o código fonte da página não é alterado. Página HTML antes da seleção do estado: Após seleção o componente aparece sem atualizar a página: