1 - O objeto XMLHttpRequest e o XML DOM
O
XMLHttpRequest é um objeto ou um conjunto de instruções de código JavaScript que permite efetuar uma conexão com um servidor usando o protocolo HTTP. Este objeto é o responsável pela parte mais importante do processamento assíncrono usando AJAX, pois é suportado por todos os navegadores de maior importância, tais como Mozilla Firefox, Internet Explorer 5+, Safari e Opera 7+.
O objeto
XMLHttpRequest trabalha nos bastidores das páginas web, ou seja, à medida que o usuário interage com a aplicação, é possível efetuar requisições a um servidor web e obter dados que possibilitarão atualizar ou validar os dados informados pelo usuário de forma assíncrona com suas atividades.
Em resumo, o funcionamento do objeto
XMLHttpRequest pode ser exemplificado na figura seguinte:
O fluxo de dados na figura acima deixa claro o envolvimento das várias tecnologias abordadas neste trabalho. Tem-se uma página HTML cujos elementos podem ser acessados e manipulados usando JavaScript (via HTML DOM). O objeto XMLHttpRequest efetua requisições ao servidor web (fornecendo alguns parâmetros) e obtém respostas em formato XML. Uma linguagem dinâmica (JSP, PHP, Perl, etc) é responsável por efetuar a conexão com o servidor de dados e retornar as informações solicitadas. Esta mesma linguagem dinâmica é a responsável por construir o documento XML e enviá-lo ao objeto XMLHttpRequest.
1.1 - Como instanciar o objeto XMLHttpRequest e verificar a compatibilidade entre navegadores
Antes de usar o objeto XMLHttpRequest para efetuar requisições a um servidor web, é preciso construí-lo usando códigos JavaScript. Esta tarefa nem sempre é fácil devido à incompatibilidade entre os navegadores em relação a este objeto.
Nos navegadores Firefox, Netscape, Safari e Opera, este objeto possui o nome de XMLHttpRequest, enquanto o Internet Explorer o implementa como um objeto ActiveX com os nomes de Microsoft.XMLHTTP ou Msxml2.XMLHTTP (dependendo das bibliotecas disponíveis no navegador). Assim, o primeiro passo na criação do objeto de requisição (XMLHttpRequest), é efetuar o teste de suporte no navegador. O trecho de código a seguir mostra como isso pode ser feito:
Antes de usar o objeto, porém, é importante verificar se este foi criado com sucesso. A abordagem mais comum é verificar se a variável que representa o objeto é diferente de null. Em JavaScript isso pode ser feito da seguinte forma:
Este trecho de código define uma variável global que receberá o objeto de requisição. Em aplicações mais complexas esta abordagem pode não ser a mais correta. O mais aconselhável é que se tenha um método responsável por construir o objeto XMLHttpRequest e retorná-lo ao chamador. Uma possível função seria:
Agora o objeto de requisição pode ser obtido a partir de qualquer parte da aplicação:
Os próximos exemplos de código funcional disponível neste artigo usam esta função para obter uma instância do objeto de requisição.
1.2 - Propriedades e métodos do objeto XMLHttpRequest
Para obter o máximo das funcionalidades do objeto de requisição, é preciso conhecer suas propriedades e métodos principais. As tabelas a seguir facilitarão este entendimento:
1.2.1 - Propriedades do objeto XMLHttpRequest
| Propriedade |
Descrição |
| onreadystatechange |
Um evento disparado a cada
vez que o estado da requisição sofre alterações.
Tal evento deve ser delegado a uma função
própria da aplicação sendo desenvolvida. |
| readyState |
Um
valor inteiro que permite monitorar o estado atual do
objeto de requisição. Possíveis
valores são:
- 0 – Objeto ainda não inicializado,
o método open() ainda não foi chamado;
- 1 – Carregando dados, o método send()
ainda não foi chamado;
- 2 – Dados carregados, o método send()
ainda não foi chamado mas os cabeçalhos
da resposta HTTP já estão disponíveis;
- 3 – Modo interativo, a propriedade responseText
já contém dados parciais;
- 4 – Operação concluída.
|
| responseText |
Resposta à requisição
em formato de texto puro |
| responseXML |
Resposta à requisição
em formato XML. Pode ser tratado como um objeto DOM Document. |
| status |
Código do status da
resposta, tal como 200 (OK), 505 (erro interno do servidor)
ou 404 (documento não encontrado). |
| statusText |
O texto associado ao status
da resposta HTTP. |
1.2.2 - Métodos do objeto XMLHttpRequest
| Método |
Descrição |
| abort() |
Cancela a requisição
HTTP. Não retorna nada |
| getAllResponseHeaders() |
Retorna
todos os cabeçalhos da resposta HTTP em formato
de texto pré-formatado. |
| getResponseHeader(string header) |
Retorna o valor do cabeçalho
especificado. |
| open(string method, string url,
string asynch) |
Prepara a requisição
HTTP, especifica o método usado (GET, POST, etc)
e se esta será ou não assíncrona.
Não retorna nada (void). |
| send(string) |
Envia a requisição
HTTP. Não retorna nada (void). |
| setHeader(string header, string
value) |
Permite definir um cabeçalho
de requisição. Deve ser chamado depois do
método open(). Não retorna nada (void). |
1.3 - O arquivo XML de testes
Para fins de demonstração das propriedades e métodos do objeto XMLHttpRequest um arquivo XML se torna necessário. O arquivo mostrado a seguir será usado para os exemplos de códigos funcionais desta seção:
Código para alunos.xml
Para sua comodidade, este arquivo XML está disponível
aqui.
1.4 - Efetuando uma requisição usando XMLHttpRequest
Uma vez entendidas as propriedades e métodos do objeto de requisição, os códigos que efetuam a requisição ao servidor web e obtém os resultados a serem analisados podem ser escritos sem maiores dificuldades. A listagem seguinte mostra como ler o conteúdo do arquivo XML apresentado no tópico 1.3 e apresentá-lo em uma caixa de mensagem:
Obs: Muitos iniciantes em AJAX enfrentam um erro muito comum ao tentarem executar uma requisição local usando o objeto XMLHttpRequest. Saiba desde já que não funciona. Para que a requisição seja feita com sucesso, o arquivo XML precisa estar em um servidor web e ser requisitado via HTTP.
Este trecho de código, quando executado, gera um resultado semelhante ao mostrado na figura a seguir:
Quer experimentar?
Clique aqui para ver o exemplo funcionando.
Obs: O objeto XMLHttpRequest não permite requisições para domínios diferentes daquele em que a página HTML está. Nosso site pode ser acessado por dois domínios: www.recomende.com e www.arquivodecodigos.net. Se o domínio for www.recomende.com, o link acima não possibilitará ver o exemplo funcionando corretamente. A descrição do erro apresentado é "Acesso negado".
Este código é a base para o perfeito entendimento das requisições usando XMLHttpRequest. Assim, uma análise cuidadosa dos passos envolvidos deve ser feita. Começando com a linha:
Aqui um objeto de requisição é obtido a partir de uma chamada ao método obterObjRequisicao(). Esta função foi apresentada na seção 1.1. O trecho seguinte:
Testa se a variável http representa um objeto de requisição válido. Caso este teste retorne verdadeiro um bloco de códigos importantes é executado. A linha:
define o endereço do documento a ser acessado. A título de estudo, o documento usado é um simples arquivo XML. Em aplicações do mundo real, o endereço poderia ser uma página dinâmica que faria uma conexão com bancos de dados, por exemplo.
A linha:
define o método que será chamado todas as vezes que o evento onreadystatechange do objeto de requisição for disparado. A linha:
efetua uma chamada à função open fornecendo o método de requisição (que pode ser GET, POST, HEAD, etc), o endereço do documento a ser acessado e define se a chamada será síncrona ou assíncrona. O valor true indica assíncrona. Finalmente a linha:
permite enviar parâmetros de requisição ao servidor. Quando o método GET é usado, o valor null deve ser definido.
O ponto de partida para o processamento das informações recebidas em resposta à requisição está dentro da função delegada ao evento onreadystatechange:
Aqui o estado é testado para verificar se a requisição está completa. Se estiver, o status do objeto de requisição é testado também. O valor 200 indica que se obteve sucesso. Para exibir o conteúdo do arquivo XML, a propriedade responseText é usada. É sempre uma boa idéia informar o usuário da aplicação de alguma falha, ou seja, tomar alguma providência quando o documento solicitado não puder ser encontrado. Assim, a função anterior poderia ser entendida para esta nova versão:
1.5 - Apresentando o XML DOM
O tópico 1.4 mostrou como é possível obter um arquivo XML como resposta a uma requisição HTTP usando o objeto XMLHttpRequest. No entanto, se as informações contidas no arquivo XML não puderem ser processadas adequadamente, todo o esforço será em vão.
O
Modelo de Objetos de Documentos XML (XML DOM) define uma forma padrão para o acesso e manipulação das informações contidas em um documento XML. Desta forma, o documento XML é apresentado como uma estrutura semelhante a uma árvore, onde os elementos, atributos e valores são definidos como nós.
O primeiro passo para acessar o XML DOM é obter uma representação a partir da resposta enviada ao objeto de requisição. Isso pode ser feita da seguinte forma:
Esta é uma pequena variação da função processar vista em tópicos anteriores. As alterações mais visíveis são:
define a variável que representará o documento XML. Tal documento é obtido na linha:
A partir daí o objeto docXML contém um documento XML pronto para ser acessado e manipulado. Um exemplo bem simples é:
Esta instrução gera a exibição da seguinte mensagem:
Esta mensagem exibe o nome do elemento principal do documento XML alunos.xml. Assim, tal documento pode ser exibido, em termos de XML DOM, da seguinte forma:
Este diagrama mostra que é possível acessar os elementos de um documento XML usando a hierarquia pai-filhos-irmãos. Por exemplo, se é fato que o elemento principal do documento pode ser acessado usando:
então seu primeiro filho nos levaria ao elemento aluno:
Então, o valor do elemento nome do primeiro elemento aluno pode ser acessado assim:
O seguinte trecho de código mostra como é possível acessar todos os elementos do documento alunos.xml e exibi-los em uma tabela HTML:
A execução deste trecho de código produzirá o seguinte resultado:
Quer experimentar?
Clique aqui e veja este exemplo em funcionamento (certifique-se de que está acessando este artigo a partir do domínio www.arquivodecodigos.net).
1.6 - Navegando pelos nós do XML DOM
A navegação pelos nós do XML DOM pode ser feita usando o relacionamento entre eles. Uma descrição deste relacionamento é apresentada a seguir:
| Elemento |
Descrição |
| parentNode |
Retorna o nó pai
de um determinado elemento |
| childNodes |
Retorna
uma lista de nós contendo todos os filhos do
nó selecionado |
| firstChild |
Retorna o primeiro filho do
elemento selecionado. |
| lastChild |
Retorna o último filho
do elemento selecionado. |
| nextSibling |
Retorna o próximo elemento
irmão, ou seja, aquele no mesmo nível da
árvore. |
| previousSibling |
Retorna o irmão anterior,
ou seja, o nó anterior no mesmo nível da
árvore. |
Um bom uso para a propriedade childNodes é quando se precisa obter a quantidade de nós filhos que um nó pai contem. O trecho de código a seguir mostra como isso pode ser feito:
1.7 - Obtendo uma lista de nós através do método getElementsByTagName
O XML DOM oferece uma forma muito conveniente de se obter apenas um determinado grupo de elementos: o método getElementsByTagName. Este método retorna uma matriz de nós cujos nomes de tags coincidem com aquele fornecido como argumento para o método. O trecho de código a seguir mostra como é possível efetuar um atalho no documento XML usado como exemplo para obter apenas os nós que contém as matrículas dos alunos:
Este código, ao ser executado, produzirá o resultado: