Usando XMLHttpRequest
por Bruno Kühnen Meneguello

Com o objeto XMLHttpRequest do JavaScript e uma página PHP com acesso a banco de dados, é possível criar uma página realmente interativa, que se atualize de maneira totalmente automática e mais importante sem a necessidade de dar reload na página. O XMLHttpRequest lhe permite checar se um número serial é correto enquanto o seu usuário ainda está no formulário, por exemplo.



O objeto XMLHttpRequest permite a comunicação assíncrona de um script (JavaScript) com qualquer página web. Ele, em síntese, faz uma requisição HTTP sem ter que iniciar uma nova janela ou recarregar os dados da janela atual.

Este objeto implementa os métodos save e load do modelo DOM. Com ele, portanto, é possível enviar e receber variáveis (ou mesmo textos inteiros) entre páginas, sem que todo o conteúdo desta tenha que ser recarregado. Para usálo adequadamente, é necessário algum conhecimento em DOM e JavaScript. De DOM, pelo menos o createElement(), createTextNode(), getElementById e o atributo innerHTML.

Como eu já disse, o XMLHttpRequest é um objeto. Mas no IE, este objeto é um ActiveX, no Mozilla e no Safari, ele é um objeto nativo. Então a chamada para ele é diferente nestes navegadores. Sendo assim:

Chamada no IE:

var req = new ActiveXObject("Microsoft.XMLHTTP");


Chamada no Mozilla/Safari:

var req = new XMLHttpRequest();


Os métodos deste objetos são:

abort():
Pára a requisição atual.

getAllResponseHeaders():
Retorna todos os cabeçalhos (labels e valores) como uma string.

getResponseHeader("headerLabel"):
Retorna o valor de um único label do cabeçalho.

open("metodo", "URL"[, asyncFlag[, "userName"[, "password"]]]):
Define a página a ser aberta, o método (GET | POST), a URL, o marcador de "assíncrono", e, se a página requerer login, o nome de usuário e a senha.

send(content):
Envia a requisição, opcionalmente pode ser uma string ou até um objeto DOM.

setRequestHeader("label", "valor"):
Define um par label + valor para ser enviado com o cabeçalho da requisição atual.

E as propriedades:

onreadystatechange:
(!) Método a ser invocado quando o estado (definido em readyState) mudar. (!)

readyState:
Inteiro representando o estado da requisição:
0 = não inicializado
1 = carregando
2 = carregado
3 = modo interativo
4 = completado

responseText:
Versão em string dos dados retornados pela requisição.

responseXML:
Objeto DOM retornado pela requisição

status:
Código numérico do estado da requisição retornado pelo servidor. O conhecido 404 "Not Found" e o menos conhecido, mas mais importante 200 "Ok"

statusText:
A string que acompanha o código de estado acima ("Not Found", "Ok", etc)



Bom, agora, pondo na prática, vamos criar um script que busque as notícias no arquivo news.php e exiba em uma div da página index.html:


<html>
...
<script language="javascript" type="text/javascript" src="script.js">
</script>
...
<div id="news"></div>
...
</html>


script.js:

var req;

function loadXMLDoc(url)
{
    req = null;
    // Procura por um objeto nativo (Mozilla/Safari)
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        req.onreadystatechange = processReqChange;
        req.open("GET", url, true);
        req.send(null);
    // Procura por uma versão ActiveX (IE)
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange = processReqChange;
            req.open("GET", url, true);
            req.send();
        }
    }
}

function processReqChange()
{
    // apenas quando o estado for "completado"
    if (req.readyState == 4) {
        // apenas se o servidor retornar "OK"
        if (req.status == 200) {
            // procura pela div id="news" e insere o conteudo 
            // retornado nela, como texto HTML
            document.getElementById('news').innerHTML = req.responseText;
        } else {
            alert("Houve um problema ao obter os dados:\n" + req.statusText);
        }
    }
}

function buscarNoticias()
{
    loadXMLDoc("http://localhost/news.php");
}

// Recarrega a cada 60000 milissegundo (60 segundos)
setInterval("buscarNoticias()", 60000);


news.php:

<?php
// Faça aqui a conexão correta ao banco de dados.
$conn mysql_connect(...);
$sql "SELECT `titulo`,`desc`,`hora`,`id` FROM news ORDER BY `hora` DESC LIMIT 5";
$query mysql_query($sql);
while (
$res mysql_fetch_array($query,MYSQL_ASSOC)) {
    echo 
"<h1>".$res['hora']." - ".$res['titulo']."</h1>";
    echo 
"<p>".$res['desc']."</p>";
    echo 
"<a href=\"news_long.php?id=".$res['id']."\">leia mais</a>";
}
?>


Bom, é isso então.

Creio ter deixado bem claro como o objeto XMLHttpRequest é útil para tornar suas páginas bem dinâmicas.

Os usos que eu ainda posso sugerir para este são vários:
- Menu cujos sub-menus sejam carregados dinamicamente.
- inputs no estilo País -> Estado -> Município -> Bairro(!) -> Rua(!) - Casa(!) totalmente dinâmico, sem sobrecarregar a página.
- Salas de bate-papo sem refresh.
- Validações diversas.

Enfim, dá para fazer, e com este objeto, fica fácil facil.

Obrigado.

por Bruno, o Kühnen.