A maioria das aplicações Web usa um modelo de solicitação/resposta para obter uma página HTML completa do servidor. Muitas vezes é um processo repetitivo de clicar em um botão, esperar a resposta do servidor, clicar em outro botão e esperar novamente. Com Ajax e o objeto XMLHttpRequest, você pode usar um modelo de solicitação/resposta que não exige que o usuário espere por uma resposta do servidor. Neste artigo, Brett McLaughlin explica como criar instâncias XMLHttpRequest que podem se adaptar a diferentes navegadores, estabelecer e enviar solicitações e responder ao servidor.
No artigo anterior desta série (consulte Recursos para obter um link), apresentamos os aplicativos Ajax e examinamos os conceitos básicos que orientam os aplicativos Ajax. No centro disso estão muitas tecnologias que você provavelmente já conhece: JavaScript, HTML e XHTML, um pouco de HTML dinâmico e o DOM (Document Object Model). Este artigo irá ampliar um ponto e focar em detalhes específicos do Ajax.
Neste artigo, você começará a entrar em contato com os objetos e métodos de programação mais básicos e fundamentais relacionados ao Ajax: o objeto XMLHttpRequest. Esse objeto é, na verdade, apenas um thread comum que abrange todos os aplicativos Ajax e, como seria de esperar, você precisa entender completamente esse objeto para realizar todo o seu potencial de programação. Na verdade, às vezes você descobrirá que, para usar XMLHttpRequest corretamente, obviamente não pode usar XMLHttpRequest. O que está acontecendo?
Visão Geral da Web 2.0
Antes de nos aprofundarmos no código, vamos dar uma olhada nas perspectivas recentes – é importante ser muito claro sobre o conceito de Web 2.0. Ao ouvir o termo Web 2.0, você deve primeiro perguntar "O que é Web 1.0?" Embora seja raro ouvir pessoas mencionarem Web 1.0, na verdade ele se refere à Web tradicional com um modelo de solicitação e resposta completamente diferente. Por exemplo, acesse o site Amazon.com e clique em um botão ou insira um termo de pesquisa. Uma solicitação é enviada ao servidor e a resposta é retornada ao navegador. A solicitação não é apenas uma lista de livros e títulos, mas outra página HTML completa. Portanto, você poderá ver oscilações ou oscilações quando o navegador redesenhar a página com o novo HTML. Na verdade, as solicitações e respostas ficam claramente visíveis a cada nova página que você vê.
A Web 2.0 elimina (em grande parte) essa interação visível de ida e volta. Por exemplo, visite um site como o Google Maps ou o Flickr (consulte Recursos para obter links para esses sites habilitados para Web 2.0 e Ajax). No Google Maps, por exemplo, você pode arrastar o mapa para aumentar e diminuir o zoom com um redesenho mínimo. É claro que ainda existem solicitações e respostas, mas elas ficam escondidas nos bastidores. Como usuário, a experiência é mais confortável e parece muito com um aplicativo de desktop. Esse novo sentimento e paradigma é o que você tem quando alguém menciona a Web 2.0.
A preocupação é viabilizar essas novas interações. Obviamente, você ainda precisa fazer solicitações e receber respostas, mas é o redesenho do HTML para cada interação solicitação/resposta que cria a sensação de interações lentas e desajeitadas na Web. Portanto, está claro que precisamos de uma maneira de enviar solicitações e receber respostas que contenham apenas os dados necessários, e não a página HTML inteira. O único momento em que você precisa obter toda a nova página HTML é quando deseja que o usuário veja a nova página.
Mas a maioria das interações adiciona detalhes às páginas existentes, modifica o texto principal ou substitui os dados originais. Nestes casos, os métodos Ajax e Web 2.0 permitem enviar e receber dados sem atualizar toda a página HTML. Para quem passa muito tempo online, essa capacidade pode fazer com que seus aplicativos pareçam mais rápidos e responsivos, fazendo com que eles voltem ao seu site de vez em quando.
Introdução ao XMLHttpRequest
Para realmente realizar esse maravilhoso milagre, você deve estar familiarizado com um objeto JavaScript, ou seja, XMLHttpRequest. Na verdade, esse pequeno objeto já existe em vários navegadores há algum tempo e está no coração da Web 2.0, do Ajax e de muitas outras coisas que abordarei nesta coluna nos próximos meses. Para lhe dar uma visão geral rápida, aqui estão apenas alguns dos métodos e propriedades que serão usados neste objeto.
·open(): Estabelece uma nova requisição ao servidor.
·send(): Envia uma solicitação ao servidor.
·abort(): Aborta a solicitação atual.
·readyState: Fornece o estado pronto do HTML atual.
·responseText: O texto de resposta da solicitação retornado pelo servidor.
Não se preocupe se você não conhece estes (ou algum deles), abordaremos cada método e propriedade nos próximos artigos. O que você deve saber agora é exatamente o que fazer com XMLHttpRequest. Observe que esses métodos e propriedades estão relacionados ao envio de solicitações e ao processamento de respostas. Na verdade, se você observar todos os métodos e propriedades de XMLHttpRequest, descobrirá que todos eles estão relacionados a um modelo de solicitação/resposta muito simples. Obviamente, não encontraremos um objeto GUI particularmente novo ou alguma maneira super misteriosa de criar interação com o usuário; usaremos solicitações e respostas muito simples. Pode não parecer muito, mas usar bem esse objeto pode revolucionar sua aplicação.
O novo simples
primeiro requer a criação de uma nova variável e a atribuição a ela de uma instância do objeto XMLHttpRequest. Isso é tão simples quanto usar a palavra-chave new no nome do objeto em JavaScript, conforme mostrado na Listagem 1.
Listagem 1. Criando um novo objeto XMLHttpRequest
<script language="javascript" type="text/javascript">
var solicitação = new XMLHttpRequest();
</script>
Não é difícil? Lembre-se de que o JavaScript não exige que você especifique tipos de variáveis; portanto, você não precisa fazer o que faz na Listagem 2 (o que pode ser feito na linguagem Java).
Listagem 2. Pseudocódigo Java para criar uma
solicitação XMLHttpRequestXMLHttpRequest = new XMLHttpRequest();
Portanto, em JavaScript você cria uma variável usando var, atribui um nome a ela (como "request") e, em seguida, atribui a ela uma nova instância XMLHttpRequest. O objeto pode então ser usado em funções.
Tratamento de erros
Todos os tipos de coisas podem realmente dar errado, e o código acima não fornece nenhum tratamento de erros. Uma abordagem melhor é criar o objeto e sair normalmente se algo der errado. Por exemplo, quaisquer navegadores mais antigos (acredite ou não, ainda existem pessoas usando versões mais antigas do Netscape Navigator) não suportam XMLHttpRequest, e você precisa informar a esses usuários que algo está errado. A Listagem 3 mostra como criar esse objeto para emitir um aviso JavaScript quando ocorrer um problema.
Listagem 3. Criando um XMLHttpRequest com recursos de tratamento de erros
<linguagem script="javascript" type="text/javascript">
var solicitação = falso;
tentar {
solicitação = novo XMLHttpRequest();
} pegar (falhou) {
solicitação = falso;
}
se (! solicitação)
alert("Erro ao inicializar XMLHttpRequest!");
</script>
Certifique-se de compreender estas etapas:
1. Crie uma nova solicitação de variável e atribua a ela um valor falso. False será usado como condição de julgamento posteriormente, o que significa que o objeto XMLHttpRequest ainda não foi criado.
2. Adicione o bloco try/catch:
1) Tente criar um objeto XMLHttpRequest.
2) Se falhar (catch (failed)), é garantido que o valor da solicitação ainda é falso.
3. Verifique se a solicitação ainda é falsa (não será falsa se tudo estiver normal).
4. Se ocorrer um problema (a solicitação é falsa), use o aviso JavaScript para notificar o usuário de que ocorreu um problema.
O código é muito simples e, para a maioria dos desenvolvedores JavaScript e web, levará mais tempo para realmente entendê-lo do que para ler e escrever o código. Agora você tem um trecho do código de criação de objeto XMLHttpRequest que é verificado por erros e pode informar o que deu errado.
Tudo parece estar bemcom a Microsoft
, pelo menos até você testar o código com o Internet Explorer. Se você experimentar assim, verá a situação ruim mostrada na Figura 1.
Figura 1. Erro de relatório do Internet Explorer
Algo está claramente errado, e o Internet Explorer dificilmente é um navegador desatualizado, já que é usado por 70% da população mundial. Em outras palavras, se você não oferecer suporte à Microsoft e ao Internet Explorer, não será popular no mundo da Web! Portanto, precisamos adotar uma abordagem diferente com os navegadores da Microsoft.
Foi verificado que a Microsoft suporta Ajax, mas sua versão XMLHttpRequest possui um nome diferente. Na verdade, ele chama isso de várias coisas diferentes. Se você usar versões mais recentes do Internet Explorer, precisará usar o objeto Msxml2.XMLHTTP, enquanto versões mais antigas do Internet Explorer usarão Microsoft.XMLHTTP. Precisamos oferecer suporte a ambos os tipos de objetos (bem como a navegadores que não sejam da Microsoft). Dê uma olhada na Listagem 4, que se baseia no código anterior e adiciona suporte para Microsoft.
A Microsoft está envolvida?
Muito tem sido escrito sobre o crescente interesse e envolvimento do Ajax e da Microsoft nesta área. Na verdade, diz-se que a versão mais recente do Internet Explorer da Microsoft – versão 7.0, prevista para o segundo semestre de 2006 – começará a suportar XMLHttpRequest diretamente, permitindo que você use a nova palavra-chave em vez de todo o código de criação Msxml2.XMLHTTP. Mas não fique muito animado, os navegadores mais antigos ainda precisam de suporte, portanto, o código entre navegadores não desaparecerá tão cedo.
Listagem 4. Adicionando suporte para navegadores Microsoft
<linguagem script="javascript" type="text/javascript">
var solicitação = falso;
tentar {
solicitação = novo XMLHttpRequest();
} pegar (tentarmicrosoft) {
tentar {
solicitação = novo ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
tentar {
solicitação = novo ActiveXObject("Microsoft.XMLHTTP");
} pegar (falhou) {
solicitação = falso;
}
}
}
se (! solicitação)
alert("Erro ao inicializar XMLHttpRequest!");
</script>
É fácil ficar confuso com essas chaves, então cada passo é apresentado abaixo:
1. Crie uma nova solicitação de variável e atribua a ela um valor falso. Use false como condição de julgamento, o que significa que o objeto XMLHttpRequest ainda não foi criado.
2. Adicione o bloco try/catch:
1) Tente criar um objeto XMLHttpRequest.
2) Se falhar (catch (trymicrosoft)):
1>Tente usar uma versão mais recente do navegador da Microsoft para criar um objeto compatível com a Microsoft (Msxml2.XMLHTTP).
2> Se falhar (catch (othermicrosoft)) tente criar um objeto compatível com Microsoft (Microsoft.XMLHTTP) usando uma versão mais antiga do navegador Microsoft.
2) Se falhar (catch (failed)), é garantido que o valor da solicitação ainda é falso.
3. Verifique se a solicitação ainda é falsa (não será falsa se tudo correr bem).
4. Se ocorrer um problema (a solicitação é falsa), use o aviso JavaScript para notificar o usuário de que ocorreu um problema.
Depois de modificar o código desta forma e testá-lo usando o Internet Explorer, você deverá ver o formulário que foi criado (sem mensagem de erro). Os resultados do meu experimento são mostrados na Figura 2.
Figura 2. Internet Explorer funcionando normalmente
Estático versus dinâmico
Dê uma outra olhada nas Listagens 1, 3 e 4. Observe que todo esse código está aninhado diretamente na tag script. Código JavaScript como esse, que não é colocado em um método ou corpo de função, é chamado de JavaScript estático. Isso significa que o código é executado em algum momento antes de a página ser exibida ao usuário. (Embora a especificação não saiba com total precisão qual efeito esse código terá no navegador quando for executado, é garantido que ele será executado antes que o usuário possa interagir com a página.) Essa também é a maneira mais geral. Os programadores Ajax criam objetos XMLHttpRequest.
Dito isto, você também poderia colocar esse código em um método como a Listagem 5.
Listagem 5. Movendo o código de criação XMLHttpRequest para um método
<script language="javascript" type="text/javascript">
var request
function createRequest() {
tentar {
solicitação = novo XMLHttpRequest();
} pegar (tentarmicrosoft) {
tentar {
solicitação = novo ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
tentar {
solicitação = novo ActiveXObject("Microsoft.XMLHTTP");
} pegar (falhou) {
solicitação = falso;
}
}
}
se (! solicitação)
alert("Erro ao inicializar XMLHttpRequest!");
}
</script>
Se você escrever seu código dessa maneira, precisará chamar esse método antes de manipular o Ajax. Portanto, código como a Listagem 6 também é necessário.
Listagem 6. Criar método usando XMLHttpRequest
<script language="javascript" type="text/javascript">
var request
function createRequest() {
tentar {
solicitação = novo XMLHttpRequest();
} pegar (tentarmicrosoft) {
tentar {
solicitação = novo ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
tentar {
solicitação = novo ActiveXObject("Microsoft.XMLHTTP");
} pegar (falhou) {
solicitação = falso;
}
}
}
se (! solicitação)
alert("Erro ao inicializar XMLHttpRequest!");
}
function getCustomerInfo() {
criarRequest();
// Faça algo com a variável request
}
</script>
O único problema com esse código é que ele atrasa a notificação de erros, e é por isso que a maioria dos programadores Ajax não usa essa abordagem. Suponha que você tenha um formulário complexo com 10 ou 15 campos, caixas de seleção, etc., e queira ativar algum código Ajax quando o usuário inserir texto no 14º campo (de cima para baixo na ordem do formulário). Neste ponto, a execução de getCustomerInfo() tenta criar um objeto XMLHttpRequest, mas (neste caso) falha. O usuário recebe então um aviso informando claramente que não pode usar o aplicativo. Mas os usuários já gastam muito tempo inserindo dados em formulários! Isso é muito chato, e ser chato obviamente não atrairá os usuários a voltarem ao seu site.
Se você usar JavaScript estático, os usuários verão mensagens de erro muito rapidamente quando clicarem na página. Isso também é chato, não é? O usuário pode acreditar erroneamente que seu aplicativo Web não pode ser executado em seu navegador. Mas certamente é melhor do que gastar 10 minutos inserindo informações apenas para ver o mesmo erro mais tarde. Portanto, recomendo escrever código estático para permitir que os usuários detectem problemas o mais cedo possível.
Apósenviar uma solicitação com XMLHttpRequest
e obter o objeto da solicitação, você pode entrar no ciclo solicitação/resposta. Lembre-se de que o único propósito do XMLHttpRequest é permitir que você envie solicitações e receba respostas. Todo o resto é trabalho de JavaScript, CSS ou outro código na página: alterar a interface do usuário, trocar imagens, interpretar dados retornados pelo servidor. Depois de preparar o XMLHttpRequest, você pode enviar a solicitação ao servidor.
Bem-vindo ao Sandbox
Ajax usa um modelo de segurança sandbox. Portanto, o código Ajax (especificamente, o objeto XMLHttpRequest) só pode enviar solicitações para o mesmo domínio em que está localizado. Abordaremos mais sobre segurança e Ajax em um artigo futuro, mas por enquanto saiba apenas que o código executado na máquina local só pode fazer solicitações para scripts do lado do servidor na máquina local. Se você deseja que o código Ajax seja executado em www.breakneckpizza.com , a solicitação deverá ser enviada a partir de um script em execução em www.breakneckpizza.com .
Para definir o URL do servidor,
você deve primeiro determinar o URL do servidor conectado. Este não é um requisito especial para Ajax, mas ainda é necessário estabelecer a conexão, e agora você obviamente deve saber como construir uma URL. Na maioria dos aplicativos, esse URL é construído a partir de uma combinação de alguns dados estáticos e dados de um formulário que o usuário processa. Por exemplo, o código JavaScript na Listagem 7 obtém o valor do campo de número de telefone e o utiliza para construir uma URL.
Listagem 7. Criando a URL de solicitação
<linguagem script="javascript" type="text/javascript">
var solicitação = falso;
tentar {
solicitação = novo XMLHttpRequest();
} pegar (tentarmicrosoft) {
tentar {
solicitação = novo ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
tentar {
solicitação = novo ActiveXObject("Microsoft.XMLHTTP");
} pegar (falhou) {
solicitação = falso;
}
}
}
se (! solicitação)
alert("Erro ao inicializar XMLHttpRequest!");
function getCustomerInfo() {
var telefone = document.getElementById("telefone").valor;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(telefone);
}
</script>
Nada difícil de entender aqui. Primeiro, o código cria uma nova variável telefone e atribui a ela o valor do campo do formulário com o ID “telefone”. A Listagem 8 mostra o XHTML deste formulário, onde você pode ver o campo phone e seu atributo id.
Listagem 8. Forma de Pizza Break Neck
<body>
<p><img src="breakneck-logo_4c.gif" alt="Pizza para quebrar o pescoço" /></p>
<form action="POST">
<p>Digite seu número de telefone:
<input type="text" size="14" nome="telefone" id="telefone"
onChange="getCustomerInfo();"
</p>
<p>Seu pedido será entregue</p>
<div id="endereço"></div>
<p>Digite seu pedido aqui:</p>
<p><textarea name="order" rows="6" cols="50" id="order"></textarea></p>
<p><input type="submit" value="Pedir Pizza" id="submit" /></p>
</form>
</body>
Observe também que quando o usuário insere um número de telefone ou altera o número de telefone, o método getCustomerInfo() mostrado na Listagem 8 é acionado. Este método obtém o número de telefone e constrói uma string de URL armazenada na variável url. Lembre-se, como o código Ajax está em área restrita e só pode se conectar ao mesmo domínio, na verdade não há necessidade de um nome de domínio na URL. O script neste exemplo é chamado /cgi-local/lookupCustomer.php. Finalmente, o número de telefone é anexado ao script como um parâmetro GET: "phone=" + escape(phone).
Se você nunca viu o método escape() antes, ele é usado para escapar de quaisquer caracteres que não possam ser enviados corretamente em texto não criptografado. Por exemplo, espaços em números de telefone serão convertidos para os caracteres %20, permitindo que esses caracteres sejam passados na URL.
Você pode adicionar quantos parâmetros forem necessários. Por exemplo, se você precisar adicionar outro parâmetro, basta anexá-lo ao URL e separá-lo com o caractere E comercial (&) [o primeiro parâmetro é separado do nome do script com um ponto de interrogação (?)].
Abra a solicitação
Depois de ter o URL ao qual se conectar, você poderá configurar a solicitação. Isso pode ser feito usando o método open() do objeto XMLHttpRequest. Este método possui cinco parâmetros:
request-type: o tipo de solicitação a ser enviada. Os valores típicos são GET ou POST, mas uma solicitação HEAD também pode ser enviada.
url: o URL ao qual se conectar.
assíncrono: verdadeiro se você deseja usar uma conexão assíncrona, caso contrário, falso. Este parâmetro é opcional e o padrão é verdadeiro.
nome de usuário: se a autenticação for necessária, você pode especificar o nome de usuário aqui. Este parâmetro opcional não possui valor padrão. senha: Se a autenticação for necessária, você pode especificar uma senha aqui. Este parâmetro opcional não possui valor padrão.
Open() abre?
Os desenvolvedores da Internet não concordam sobre o que exatamente o método open() faz. Mas na verdade não abre uma solicitação. Se você monitorar a rede e a transferência de dados entre uma página XHTML/Ajax e seu script de conexão, você não verá nenhuma comunicação quando o método open() for chamado. Não está claro por que esse nome foi escolhido, mas claramente não é uma boa escolha.
Normalmente os três primeiros parâmetros são usados. Na verdade, mesmo que seja necessária uma conexão assíncrona, o terceiro parâmetro deve ser especificado como "true". Este é o padrão, mas insistir em especificar explicitamente se a solicitação é assíncrona ou síncrona é mais fácil de entender.
Combiná-los geralmente resulta em uma linha de código como a mostrada na Listagem 9.
Listagem 9.
Função de solicitação aberta getCustomerInfo() {
var telefone = document.getElementById("telefone").valor;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(telefone);
request.open("GET", url, verdadeiro);
}
Depois de configurar o URL, o resto é fácil. Para a maioria das solicitações, GET é suficiente (você verá quando o POST é necessário em um artigo posterior), mais a URL, e isso é tudo que você precisa para usar o método open().
Desafiando a assincronicidade
No próximo artigo desta série, passarei muito tempo escrevendo e usando código assíncrono, mas você deve entender por que o último parâmetro de open() é tão importante. Em um modelo geral de solicitação/resposta, como Web 1.0, o cliente (um navegador ou código executado na máquina local) faz uma solicitação ao servidor. A solicitação é síncrona, ou seja, o cliente aguarda uma resposta do servidor. Quando o cliente estiver esperando, você será notificado da espera de pelo menos alguma forma:
·Ampulheta (especialmente no Windows).
·Bola giratória (geralmente em máquinas Mac).
·O aplicativo basicamente congela e depois de um tempo o cursor muda.
É exatamente por isso que os aplicativos Web parecem desajeitados ou lentos – uma falta de interatividade verdadeira. Quando o botão é pressionado, o aplicativo fica efetivamente inutilizável até que a solicitação que acabou de ser acionada seja respondida. Se a solicitação exigir muito processamento do servidor, o tempo de espera poderá ser longo (pelo menos neste mundo de multiprocessadores e DSL sem espera).
As solicitações assíncronas não aguardam uma resposta do servidor. O aplicativo continua em execução após o envio da solicitação. Os usuários ainda podem inserir dados no formulário da Web ou até mesmo sair do formulário. Não há bolas giratórias ou ampulhetas e o aplicativo não congela visivelmente. O servidor responde silenciosamente à solicitação e, quando terminar, informa ao solicitante original que o trabalho foi concluído (você verá quando). O resultado é um aplicativo que parece menos lento ou lento e mais responsivo, interativo e muito mais rápido. Esta é apenas uma parte da Web 2.0, mas é uma parte importante. Todos os antigos componentes GUI e paradigmas de design da Web não conseguem superar o modelo lento e síncrono de solicitação/resposta.
Enviando Solicitações
Uma vez configurado com open(), você pode enviar solicitações. Felizmente, o método de envio de requisições tem um nome mais apropriado que open(): é send().
send() possui apenas um parâmetro, que é o conteúdo a ser enviado.
Mas antes de considerar este método, lembre-
se que você já enviou dados através da própria URL:
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
, Mas também é possível enviar dados pela própria URL. Na verdade, com solicitações GET (que ocorrem em cerca de 80% dos aplicativos Ajax típicos), é muito mais fácil enviar dados usando uma URL. Se você precisar enviar informações seguras ou XML, considere usar send() para enviar o conteúdo (dados seguros e mensagens XML serão discutidos em artigos subsequentes desta série). Caso não precise passar dados por send(), basta passar null como parâmetro deste método. Portanto, você descobrirá que isso é tudo o que precisa fazer nos exemplos deste artigo (consulte a Listagem 10).
Listagem 10. Enviar
função de solicitação getCustomerInfo() {
var telefone = document.getElementById("telefone").valor;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(telefone);
request.open("GET", url, verdadeiro);
solicitação.enviar(nulo);
}
Especifique o método de retorno de chamada
Há muito pouco sobre o que fazemos agora que seja novo, revolucionário ou assíncrono. Deve-se admitir que a pequena palavra-chave “true” no método open() estabelece uma solicitação assíncrona. Mas fora isso, o código não é diferente de programar com servlets Java e JSP, PHP ou Perl. Então, qual é o maior segredo do Ajax e da Web 2.0? O segredo está em uma propriedade simples onreadystatechange de XMLHttpRequest.
Certifique-se de entender primeiro o fluxo neste código (revise a Listagem 10 se necessário). Crie sua solicitação e depois faça a solicitação. Além disso, como a solicitação é assíncrona, o método JavaScript (getCustomerInfo() no exemplo) não espera pelo servidor. Assim o código continuará em execução, ou seja, o método sairá e o controle retornará ao formulário. O usuário pode continuar inserindo informações e o aplicativo não espera pelo servidor.
Isso levanta uma questão interessante: o que acontece depois que o servidor conclui a solicitação? A resposta é que nada acontece, pelo menos para o código atual! Obviamente isso não funcionará, então o servidor precisa de algum tipo de instrução sobre o que fazer após terminar de processar a solicitação enviada a ele via XMLHttpRequest.
Funções de referência em JavaScript:
JavaScript é uma linguagem de tipo fraco e você pode usar variáveis para referenciar qualquer coisa. Portanto, se você declarar uma função updatePage(), o JavaScript também tratará o nome da função como uma variável. Em outras palavras, você pode referenciar a função em seu código usando o nome da variável updatePage.
Listagem 11. Definir método de retorno de chamada
function getCustomerInfo() {
var telefone = document.getElementById("telefone").valor;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(telefone);
request.open("GET", url, verdadeiro);
request.onreadystatechange = updatePage;
solicitação.enviar(nulo);
}
É importante observar onde no código esta propriedade está definida - ela é definida antes de send() ser chamado. Esta propriedade deve ser configurada antes do envio da solicitação para que o servidor possa visualizá-la após responder a solicitação concluída. Agora só falta escrever o método updatePage(), que é o foco da última seção deste artigo.
O servidor de processamento responde
à solicitação, o usuário usa o formulário da Web com satisfação (enquanto o servidor processa a solicitação) e agora o servidor concluiu o processamento da solicitação. O servidor analisa o atributo onreadystatechange para determinar qual método chamar. Caso contrário, trate sua aplicação como qualquer outra aplicação, seja assíncrona ou não. Em outras palavras, você não precisa necessariamente realizar nenhuma ação especial para escrever um método que responda ao servidor, você só precisa alterar o formulário, deixar o usuário visitar outra URL ou fazer o que o servidor de resposta precisar. Nesta seção nos concentramos nas respostas ao servidor e em uma ação típica - alterar instantaneamente parte do formulário que o usuário vê.
Callbacks e Ajax
Agora vimos como dizer ao servidor o que fazer quando terminar: defina a propriedade onreadystatechange do objeto XMLHttpRequest como o nome da função a ser executada. Desta forma, a função será chamada automaticamente após o servidor processar a solicitação. Também não há necessidade de se preocupar com nenhum parâmetro da função. Começamos com um método simples, mostrado na Listagem 12.
Listagem 12. Código para o método de retorno de chamada
<linguagem script="javascript" type="text/javascript">
var solicitação = falso;
tentar {
solicitação = novo XMLHttpRequest();
} pegar (tentarmicrosoft) {
tentar {
solicitação = novo ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
tentar {
solicitação = novo ActiveXObject("Microsoft.XMLHTTP");
} pegar (falhou) {
solicitação = falso;
}
}
}
se (! solicitação)
alert("Erro ao inicializar XMLHttpRequest!");
function getCustomerInfo() {
var telefone = document.getElementById("telefone").valor;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(telefone);
request.open("GET", url, verdadeiro);
request.onreadystatechange = updatePage;
solicitação.enviar(nulo);
}
function updatePage() {
alert("Servidor concluído!");
}
</script>
Ele apenas emite alguns avisos simples para avisar quando o servidor completou sua tarefa. Experimente esse código em sua própria página da Web e abra-o em um navegador (consulte a Listagem 8 se desejar ver o XHTML neste exemplo). Digite o número do telefone e saia do campo, você verá uma janela pop-up de aviso (como mostrado na Figura 3), mas clique em OK e ela aparecerá novamente...
Figura 3. Código Ajax para o aviso pop-up
Dependendo do navegador, você poderá ver dois, três ou até quatro avisos antes que o formulário pare de aparecer. O que está acontecendo? Acontece que não consideramos o estado de prontidão do HTTP, que é uma parte importante do ciclo de solicitação/resposta.
Estado pronto para HTTP
Conforme mencionado anteriormente, o servidor procura o método a ser chamado no atributo onreadystatechange de XMLHttpRequest após concluir a solicitação. Isto é verdade, mas incompleto. Na verdade, ele chama esse método sempre que o status de pronto para HTTP muda. O que isto significa? Primeiro você deve entender o estado de prontidão do HTTP.
O status HTTP pronto representa o status ou condição da solicitação. É usado para determinar se a solicitação foi iniciada, recebeu uma resposta ou se o modelo de solicitação/resposta foi concluído. Também pode ajudar a determinar se é seguro ler o texto de resposta ou os dados fornecidos pelo servidor. Existem cinco estados de prontidão que você deve conhecer em aplicações Ajax:
·0: A solicitação não foi emitida (antes de open() ser chamado).
·1: A solicitação foi estabelecida mas ainda não foi enviada (antes da chamada de send()).
·2: A solicitação foi enviada e está sendo processada (o cabeçalho do conteúdo geralmente pode ser obtido na resposta).
·3: A solicitação foi processada e alguns dados geralmente estão disponíveis na resposta, mas o servidor não completou a resposta.
·4: A resposta está completa e você pode acessar a resposta do servidor e utilizá-la.
Tal como acontece com a maioria dos problemas entre navegadores, esses estados prontos não são usados de forma consistente. Você pode esperar que o status de prontidão da tarefa vá de 0 para 1, para 2, para 3, para 4, mas isso raramente é o caso. Alguns navegadores nunca informam 0 ou 1, mas começam diretamente com 2, depois 3 e 4. Outros navegadores relatam todos os status. Outros relatam o status de pronto 1 várias vezes. Como visto na seção anterior, o servidor chama updatePage() várias vezes e uma caixa de aviso aparece toda vez que é chamado - pode ser diferente do esperado!
Para programação Ajax, o único estado que precisa ser tratado diretamente é o estado pronto 4, que indica que a resposta do servidor está completa e os dados de resposta são seguros para uso. Com base nisso, a primeira linha do método de retorno de chamada deve ser semelhante à Listagem 13.
Listagem 13. Verificando
a função de prontidão updatePage() {
if (solicitação. readyState == 4)
alert("Servidor concluído!");
}
Após a modificação, você pode garantir que o processamento do servidor foi concluído. Tente executar a nova versão do código Ajax e você verá a mensagem de aviso exibida apenas uma vez, conforme esperado.
Códigos de status HTTP
Embora o código na Listagem 13 pareça bom, há um problema – e se o servidor responder à solicitação e concluir o processamento, mas relatar um erro? Esteja ciente de que o código do lado do servidor deve entender que está sendo chamado por Ajax, JSP, formulários HTML simples ou outros tipos de código, mas só pode relatar informações usando métodos tradicionais específicos da Web. No mundo Web, o código HTTP pode lidar com vários problemas que podem ocorrer na solicitação.
Por exemplo, você deve ter encontrado a situação em que inseriu a solicitação de URL errada e recebeu um código de erro 404, o que significa que a página não existe. Este é apenas um dos muitos códigos de erro que podem ser recebidos com uma solicitação HTTP (consulte o link em Recursos para obter uma lista completa de códigos de status). 403 e 401, que indicam que os dados acessados estão protegidos ou proibidos, também são comuns. Em ambos os casos, estes códigos de erro são obtidos a partir da resposta completa. Em outras palavras, o servidor atendeu à solicitação (ou seja, o status HTTP pronto é 4), mas não retornou os dados esperados pelo cliente.
Portanto, além do status pronto, você também precisa verificar o status HTTP. O código de status esperado é 200, o que significa que tudo correu bem. Se o status pronto for 4 e o código de status for 200, você poderá processar os dados do servidor, e os dados deverão ser os dados solicitados (em vez de erros ou outras informações problemáticas). Portanto, também precisamos adicionar uma verificação de status no método de retorno de chamada, conforme mostrado na Listagem 14.
Listagem 14. Verifique
a função do código de status HTTP updatePage() {
if (solicitação. readyState == 4)
se (solicitação.status == 200)
alert("Servidor concluído!");
}
Para adicionar um tratamento de erros mais robusto e tentar evitar complicações excessivas adicionando uma ou duas verificações de código de status, dê uma olhada na versão modificada de updatePage() na Listagem 15.
Listagem 15. Adicione uma pequena
função de verificação de erros updatePage() {
if (solicitação. readyState == 4)
se (solicitação.status == 200)
alert("Servidor concluído!");
senão se (request.status == 404)
alert("URL de solicitação não existe");
outro
alert("Erro: o código de status é " + request.status);
}
Agora altere a URL em getCustomerInfo() para uma URL inexistente e veja o que acontece. Você deverá ver uma mensagem de aviso informando que o URL solicitado não existe – ótimo! É difícil lidar com todas as condições de erro, mas essa pequena alteração pode cobrir 80% dos problemas em um aplicativo típico da Web.
A leitura do texto da resposta
agora garante que a solicitação tenha sido processada (através do status pronto), o servidor deu uma resposta normal (através do código de status) e, finalmente, podemos processar os dados retornados pelo servidor. Os dados retornados são armazenados na propriedade RespoteText do objeto xmlHttPrequest.
O conteúdo do texto em RespoteText, como formato e comprimento, é intencionalmente deixado vago. Dessa forma, o servidor pode definir o texto para qualquer coisa. Por exemplo, um script pode retornar valores separados por vírgula, outro usa um tubo (o caráter | Cabe ao servidor decidir para onde ir.
No exemplo usado neste artigo, o servidor retorna o último pedido e o endereço do cliente do cliente, separados por um caractere de tubulação. O pedido e o endereço são usados para definir valores de elemento no formulário.
Listagem 16. Manipulação
da função de resposta ao servidor UpdatePage () {
if (request.readyState == 4) {
if (request.status == 200) {
var resposta = request.ResponseTxt.split ("|");
document.getElementById ("Order"). Value = Resposta [0];
document.getElementById ("endereço"). INnerHTML =
resposta [1] .Prace (/ n/g, "");
} outro
alerta ("status é" + request.status);
}
}
Primeiro, obtenha o responseText e divida -o do tubo usando o método javascript split (). A matriz resultante é colocada em resposta. O primeiro valor na matriz - o pedido anterior - é acessado com resposta [0] e é definido como o valor do campo com o ID "Order". A segunda resposta de valor [1], o endereço do cliente, requer um pouco mais de processamento. Como as linhas no endereço são separadas por caracteres normais de separadores de linha (" n"), o código precisa usar os separadores de linha no estilo XHTML <br />. O processo de substituição é realizado usando a função substituir () e expressões regulares. Finalmente, o texto modificado é usado como HTML interno no formulário HTML div. O resultado é que o formulário atualiza repentinamente com as informações do cliente, conforme mostrado na Figura 4.
Figura 4. Break Neck Form após receber dados do cliente
Antes de encerrar este artigo, gostaria de apresentar outro atributo importante do xmlHttPrequest, ResponseXML. Esta propriedade contém (como você deve ter adivinhado) a resposta XML se o servidor optar por usar uma resposta XML. O processamento de respostas XML é muito diferente do processamento de texto comum, envolvendo análise, modelo de objeto de documentos (DOM) e outros problemas. O XML será abordado mais adiante em um artigo posterior. Mas como o ResponseXML é geralmente discutido em conjunto com o RespoteText, ele merece uma menção aqui. Para muitos aplicativos AJAX simples, o RespoText será suficiente, mas em breve você verá que o XML também poderá ser bem tratado com aplicativos AJAX.
Conclusão
Você pode estar um pouco cansado de xmlhttprequest. Mas você usará esse objeto repetidamente em todas as páginas e aplicativos que você escreve usando AJAX. Francamente, há algo a ser dito para xmlhttprequest. O próximo artigo introduzirá como usar o post e obter solicitações para definir cabeçalhos de conteúdo em solicitações e ler cabeçalhos de conteúdo das respostas do servidor e entender como codificar solicitações e processar XML no modelo de solicitação/resposta.
Mais tarde, introduziremos caixas de ferramentas comuns do Ajax. Essas caixas de ferramentas realmente escondem muitos dos detalhes descritos neste artigo, facilitando a programação do AJAX. Você pode se perguntar por que precisa codificar os detalhes de baixo nível quando existem tantas caixas de ferramentas por aí. A resposta é que é difícil identificar problemas em um aplicativo sem saber o que o aplicativo está fazendo.
Portanto, não ignore os detalhes ou simplesmente navegue e, se algo der errado com esta caixa de ferramentas útil e linda, você não precisará arranhar a cabeça ou enviar um email para suportar. Se você entender como usar o XMLHTTPREQUEST diretamente, você achará fácil depurar e resolver os problemas mais estranhos. Uma caixa de ferramentas só é boa se você deixar resolver seus problemas.
Então, familiarize -se com o XMLHTTPREQUEST. De fato, se você possui código AJAX que usa a caixa de ferramentas, tente reescrevê -lo usando o objeto XMLHTTPREQUEST e suas propriedades e métodos. Este é um bom exercício para ajudá -lo a entender melhor os princípios.
O próximo artigo discutirá ainda mais esse objeto, explorando algumas de suas propriedades mais interessantes (como ResponseXML) e como usar solicitações de postagem e enviar dados em diferentes formatos. Comece a escrever o código e discutiremos isso novamente em um mês.