Nenhum produto encontrado nessa seleção.
Você já deve ter notado que algumas páginas web utilizam recursos que atualizam os dados da página sem enviar uma nova requisição para o servidor. Isso, provavelmente, é Ajax em Javascript.
Ajax (Asynchronous Javascript and XML) é o uso das tecnologias providas pelos navegadores (como Javascript e XML), para tornar páginas mais interativas com o usuário, utilizando-se de solicitações assíncronas de informações.
Assíncrona quer dizer que a solicitação pode ser enviada "por baixo dos panos" para o servidor, e o usuário não tem que parar e esperar que o processo termine. Os dados são retornados para o cliente como texto, JSON, XML, ou como o desenvolvedor preferir. Este último, por sua vez, pode fazer o que quiser com os dados, como atualizar o conteúdo de um elemento da página, mostrar um erro (se for o caso) ou até mesmo atualizar o conteúdo da página inteira.
Para fazer toda a mágica acontecer, utilizamos um objeto especial chamado XMLHttpRequest, que gerencia a comunicação assíncrona entre o servidor e o cliente. Porém, se você ainda suportar o IE6, terá que fazer aqueles malabarismos, que já conversamos várias vezes em artigos anteriores, para alternar entre o objeto XMLHttpRequest e o ActiveXObject, que é o que funciona com versões antigas do Internet Explorer, como o IE6.
Para sua sorte, do IE7 em diante, XMLHttpRequest é suportado.
Agora chega de conversa e vamos ver códigos, que é o que interessa pra gente.
Acertando o meio de campo
Normalmente, precisamos que algum evento aconteça para que a página seja atualizada, e para que um evento aconteça, é claro que precisamos ter algo em HTML para o usuário interagir.
Vamos criar a página HTML, chamar nosso script .js e colocar dois elementos dentro do body: um link (a) e uma div.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Página</title> <script src="meu_script.js"></script> </head> <body> <a href="" id="clique">Clique</a> <div id="minha_div"></div> </body> </html>
Dica: Modifique a codificação do seu editor de textos para UTF-8.
Como vamos fazer uma requisição para chamar outro arquivo dentro do nosso servidor, crie um novo arquivo HTML com o nome que você preferir e coloque algum texto dentro dele. Veja meu arquivo chamado de texto.html:
<h1>Texto</h1> <p>Olha só! Sou um texto.</p>
Agora podemos trabalhar em nosso arquivo Javascript.
O evento click
Como estamos trabalhando dentro de um evento de clique na página, precisamos capturar este evento.
Veja como fazer isso:
// Captura o evento load da página window.onload=function(){ // Localiza o elemento a pelo id var a = document.getElementById('clique'); // Captura o evento click no a a.onclick=function(){ // Uma função genérica geral(); // Retorna falso para não atualizar a página return false; } } geral = function(){ // TRABALHAREMOS AQUI }
Perceba que essa não é a melhor maneira para capturar eventos (veja eventos em Javascript), mas vamos continuar este artigo, até pouco antes do fim, utilizando este método para que os exemplos fiquem menores e fáceis para serem entendidos. Além disso, para facilitar ainda mais, tudo o que você vai ver abaixo estará exatamente onde escrevi // TRABALHAREMOS AQUI, quando for diferente disso, vou dizer.
Feito isso, vamos começar a criar a nossa requisição Ajax.
Mundo dos sonhos: XMLHttpRequest
Se vivêssemos em um mundo onde todos os navegadores fossem novos e aceitassem todas as maravilhas que as novidades nos oferecem, seria só criar uma instância do objeto XMLHttpRequest e mandar a requisição, como mostro abaixo:
Como vimos no artigo anterior, criaremos uma instância do objeto XMLHttpRequest:
// Cria o objeto XMLHttpRequest var chamada = new XMLHttpRequest();
Agora que a instância "chamada" está criada, vamos detalhar o que precisamos abrir:
// Configura os parâmetros do arquivo que será aberto chamada.open('GET', 'texto.html', true);
Para resumir, o método "open" do objeto XMLHttpRequest, recebe os seguintes parâmetros: "POST" ou "GET" (existem outros, mas só precisamos de POST e GET por agora), o arquivo que deverá ser aberto (qualquer arquivo no mesmo domínio), e true para conexão assíncrona ou false para síncrona (Veja detalhes aqui).
Agora precisamos enviar os dados para o servidor. Como não estamos enviando nenhum parâmetro, utilizamos o método "send" com um valor null.
// Envia a requisição chamada.send(null);
Agora temos que verificar se a conexão foi realizada com sucesso. Para isso, vamos utilizar o método onreadystatechange para capturar as mudanças de estados do evento que ocorrendo no objeto XMLHttpRequest.
// Verifica os estados do objeto XMLHttpRequest chamada.onreadystatechange = function(){ // Verifica se a página foi carregada completamente sem erros if ( this.readyState == 4 && this.status == 200 ) { // Localiza nossa div com id minha_div var div = document.getElementById('minha_div'); // Adiciona o conteúdo do texto.html na div div.innerHTML = this.responseText; } };
Onreadystatechange recebe uma função para tratar dos estados que estão ocorrendo para a nossa requisição (que vão de 0 a 4). O estado – que está na propriedade readyState – mais importante para a nossa requisição, é o 4, que indica que o arquivo terminou de ser carregado e já temos o resultado. Além disso, verificamos também a resposta do servidor, que neste caso, 200 significa que o arquivo foi carregado sem erros.
Sabendo que no trecho acima tudo está correto, podemos fazer o que quisermos com a resposta do servidor.
Eu simplesmente peguei o texto retornado pelo servidor com chamada.responseText ou this.responseText, e o incluí em nossa DIV de exemplo:
Como você pode ver na imagem acima, após clicar no link, o texto que estava no arquivo "texto.html", foi enviado diretamente para a nossa DIV sem atualizar a página.
É claro que não vivemos no mundo dos sonhos. Precisamos verificar várias coisas além do que foi descrito acima para ter a certeza que nosso script vai funcionar em todos os navegadores. Porém, os trechos de código acima nos dão um começo para entender como Ajax funciona na vida real.
Abaixo o código completo:
// Captura o evento load da página window.onload=function(){ // Localiza o elemento a pelo id var a = document.getElementById('clique'); // Captura o evento click no a a.onclick=function(){ // Uma função genérica geral(); // Retorna falso para não atualizar a página return false; } } geral = function(){ // Cria o objeto XMLHttpRequest var chamada = new XMLHttpRequest(); // Configura os parâmetros do arquivo que será aberto chamada.open('GET', 'texto.html', true); // Envia a requisição chamada.send(null); // Verifica os estados do objeto XMLHttpRequest chamada.onreadystatechange = function(){ // Verifica se a página foi carregada completamente sem erros if ( this.readyState == 4 && this.status == 200 ) { // Localiza nossa div com id minha_div var div = document.getElementById('minha_div'); // Adiciona o conteúdo do texto.html na div div.innerHTML = this.responseText; } }; };
Lembre-se que isso não funciona com o IE6, e que você não deve mais utilizar o método de captura de eventos que mencionei acima, prefira sempre addEventListener ou attachEvent, que já expliquei aqui no TutsUP.
Agora vamos para o mundo real.
XMLHttpRequest e ActiveXObject
A primeira coisa para que nosso código funcione no IE6, será modificar o objeto XMLHttpRequest para ActiveXObject. E, para que continuemos dando suporte para todos os navegadores, teremos que utilizar estruturas condicionais.
Veja:
// Cria o objeto XMLHttpRequest var chamada; if (window.XMLHttpRequest) { // Mozilla, Safari, ... chamada = new XMLHttpRequest(); } else if (window.ActiveXObject) { // IE 6 e anteriores chamada = new ActiveXObject("Microsoft.XMLHTTP"); }
Agora sim, se XMLHttpRequest não existir no objeto window, configuramos nossa chamada para o objeto ActiveXObject.
Simples assim!
Agora configuramos o método "open", da mesma maneira:
// Configura os parâmetros do arquivo que será aberto chamada.open('GET', 'texto.html', true);
Em seguida configuramos o onreadystatechange, porém, devemos trocar a palavra "this", pelo nome da instância do objeto ActiveXObject, em nosso caso, "chamada".
// Verifica os estados do objeto XMLHttpRequest chamada.onreadystatechange = function(){ // Verifica se a página foi carregada completamente sem erros if ( chamada.readyState == 4 && chamada.status == 200 ) { // Localiza nossa div com id minha_div var div = document.getElementById('minha_div'); // Adiciona o conteúdo do texto.html na div div.innerHTML = chamada.responseText; } };
Por fim, enviamos a requisição:
// Envia a requisição chamada.send(null);
POST e GET
Não faz sentido fazer requisições para o servidor, se não vamos postar nem obter nada em troca.
Por exemplo: suponhamos que você tenha um formulário e queira enviá-lo para o servidor utilizando os métodos POST ou GET, como você enviaria isso via AJAX?
Para isso, é necessário configurar o método setRequestHeader da seguinte maneira:
chamada.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
No trecho acima, configuramos o MIME Type da aplicação, como costumamos fazer com nossos arquivos HTML.
Agora, se você quiser postar algo, pode fazer assim:
POST
// Cria o objeto XMLHttpRequest var chamada; if (window.XMLHttpRequest) { // Mozilla, Safari, ... chamada = new XMLHttpRequest(); } else if (window.ActiveXObject) { // IE 6 e anteriores chamada = new ActiveXObject("Microsoft.XMLHTTP"); } // Configura os parâmetros do arquivo que será aberto chamada.open('POST', 'texto.php', true); chamada.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // Verifica os estados do objeto XMLHttpRequest chamada.onreadystatechange = function(){ // Verifica se a página foi carregada completamente sem erros if ( chamada.readyState == 4 && chamada.status == 200 ) { // Localiza nossa div com id minha_div var div = document.getElementById('minha_div'); // Adiciona o conteúdo do texto.html na div div.innerHTML = chamada.responseText; } }; // Envia a requisição chamada.send('valor1=' + encodeURIComponent('Meu valor 1') + '&' + 'valor2=' + encodeURIComponent('Meu valor 2') + '&' + 'valor3=' + encodeURIComponent('Meu valor 3') );
A parte do nosso código que mudou foi:
// Configura os parâmetros do arquivo que será aberto chamada.open('POST', 'texto.php', true); chamada.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
Ao invés de GET, utilizamos POST, e adicionamos uma nova linha para configurar o MIME Type.
Outra parte que mudou foi a seguinte:
// Envia a requisição chamada.send('valor1=' + encodeURIComponent('Meu valor 1') + '&' + 'valor2=' + encodeURIComponent('Meu valor 2') + '&' + 'valor3=' + encodeURIComponent('Meu valor 3') );
Você envia o valor para send() no seguinte formato:
"parâmetro=valor&parâmetro2=valor2"
Para garantir que nossos dados cheguem do outro lado de maneira segura, utilizamos encodeURIComponent, que assegura que os caracteres inválidos sejam codificados para um formato de URI.
Pronto, os dados chegam do outro lado como um array (em PHP, no caso):
Array ( [valor1] => Meu Atenção 1 [valor2] => Meu valor 2 [valor3] => Meu valor 3 )
GET
Se você quiser passar parâmetros por GET, deve modificar a URL que você envia para o método open:
chamada.open('GET', 'texto.php?param1=' + encodeURIComponent('Meu valor') + '&' + 'param2=' + encodeURIComponent('Meu valor 2') + '&' + 'param3=' + encodeURIComponent('Meu valor 3'), true);
Aqui os parâmetros são enviados diretamente na URL, por exemplo:
"teste.php?param1=Valor 1¶m2=Valor 2"
Veja o código completo:
// Captura o evento load da página window.onload=function(){ // Localiza o elemento a pelo id var a = document.getElementById('clique'); // Captura o evento click no a a.onclick=function(){ // Uma função genérica geral(); // Retorna falso para não atualizar a página return false; } } geral = function(){ // Cria o objeto XMLHttpRequest var chamada; if (window.XMLHttpRequest) { // Mozilla, Safari, ... chamada = new XMLHttpRequest(); } else if (window.ActiveXObject) { // IE 6 e anteriores chamada = new ActiveXObject("Microsoft.XMLHTTP"); } // Configura os parâmetros do arquivo que será aberto chamada.open('GET', 'texto.php?param1=' + encodeURIComponent('Meu valor') + '&' + 'param2=' + encodeURIComponent('Meu valor 2') + '&' + 'param3=' + encodeURIComponent('Meu valor 3'), true); chamada.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // Verifica os estados do objeto XMLHttpRequest chamada.onreadystatechange = function(){ // Verifica se a página foi carregada completamente sem erros if ( chamada.readyState == 4 && chamada.status == 200 ) { // Localiza nossa div com id minha_div var div = document.getElementById('minha_div'); // Adiciona o conteúdo do texto.html na div div.innerHTML = chamada.responseText; } }; // Envia a requisição chamada.send(null); };
Perceba que você vai ter que utilizar uma linguagem que não funcione só do lado do cliente, mas também no lado do servidor, para receber os dados de POST ou GET. Optei por PHP, mas você pode utilizar a linguagem que preferir.
No meu caso, estava só verificando se POST ou GET estavam sendo recebidos pelo arquivo texto.php.
Nele só tem algumas linhas de código:
<?php $a = $_GET + $_POST; print_r($a);
O trecho acima simplesmente atribui GET ou POST para uma variável, e imprime o resultado da mesma.
addEventListener ou attachEventListener
Certo, agora vamos deixar o nosso código um pouco mais moderno.
Lembra que eu disse que não era interessante utilizar o método de captura de eventos que utilizei nos exemplos anteriores? Isso porque você só pode adicionar um evento load (por exemplo) na página. Se você estiver utilizando outras bibliotecas externas que utilizam este mesmo tipo de captura de eventos (que é um pouco improvável), terá problemas.
Então veja aquele código dos exemplos acima com o modelo de captura de eventos DOM Nível 2.
// Função para capturar eventos function captura_eventos(objeto, evento, funcao) { // Testa se o navegador suporta addEventListener if (objeto.addEventListener) { // Adiciona addEventListener objeto.addEventListener(evento, funcao, true); } // Testa se o navegador suporta attachEvent else if (objeto.attachEvent) { // Adiciona a palavra on no evento var evento = 'on' + evento; // Adicionar attachEvent objeto.attachEvent(evento, funcao); } } // Função para cancelar os eventos function cancela_evento(evento) { // Testa se o navegador suporta stopPropagation if (evento.stopPropagation) { // Adiciona stopPropagation evento.stopPropagation(); // Adiciona preventDefault evento.preventDefault(); } else { // Configura returnValue como false para o IE evento.returnValue = false; // Cancela a propagação para o IE evento.cancelBubble = true; } } // Função geral para rodar após o load da página function manipula_load() { // Função para capturar o click no a captura_eventos(document.getElementById('clique'), 'click', geral); } // Captura o evento load captura_eventos( window, 'load', manipula_load ); var geral = function(evento){ // Configura o evento em uma variável var evento = evento ? evento : window.event; // Cria o objeto XMLHttpRequest var chamada; if (window.XMLHttpRequest) { // Mozilla, Safari, ... chamada = new XMLHttpRequest(); } else if (window.ActiveXObject) { // IE 6 e anteriores chamada = new ActiveXObject("Microsoft.XMLHTTP"); } // Configura os parâmetros do arquivo que será aberto chamada.open('GET', 'texto.php?param1=' + encodeURIComponent('Meu valor') + '&' + 'param2=' + encodeURIComponent('Meu valor 2') + '&' + 'param3=' + encodeURIComponent('Meu valor 3'), true); chamada.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // Verifica os estados do objeto XMLHttpRequest chamada.onreadystatechange = function(){ // Verifica se a página foi carregada completamente sem erros if ( chamada.readyState == 4 && chamada.status == 200 ) { // Localiza nossa div com id minha_div var div = document.getElementById('minha_div'); // Adiciona o conteúdo do texto.html na div div.innerHTML = chamada.responseText; } }; // Envia a requisição chamada.send(null); // Cancela o evento e não atualiza a página cancela_evento(evento); };
De início, pode parecer algo muito complicado, mas estou simplesmente juntando partes de código que você já viu anteriormente em outros artigos.
Por exemplo, falamos sobre isso em:
Se você tiver dúvidas quanto a eventos, releia os artigos anteriores.
Concluindo
É claro que trabalhar com Ajax em Javascript não é só isso que demonstrei anteriormente, existem mais propriedades e métodos que você pode utilizar, e mais conhecimento que você pode conseguir procurando mais sobre uma parte em específico dos trechos que detalhei. Porém, o artigo que você acabou de ler, da uma noção geral sobre como é possível sair da página sem necessariamente fazer uma nova requisição ao servidor. Espero que tenha entendido.
Se não entendeu, só comentar que vamos ajudar.
Outras aulas
Caso tenha perdido a aula anterior, segue o link:
Próxima aula:
Caso queira visualizar todas as aulas dessa sessão em ordem cronológica invertida: