Nenhum produto encontrado nessa seleção.
Ajax e JSON são uma combinação perfeita para transitar dados entre o cliente e o servidor sem ter que atualizar a página ou sofrer para manipular os dados retornados por requisições XMLHttpRequest, em XML, HTML ou texto puro.
Ontem mostrei um tutorial com várias informações sobre como utilizar Ajax para poder enviar e receber dados do lado do cliente para o lado do servidor sem ter que atualizar a página.
Hoje vamos continuar na mesma linha de raciocínio, porém, também aprenderemos a criar e manipular dados de notação de objeto JavaScript (JSON).
JSON
Talvez você já saiba, mas vale ressaltar: JSON (JavaScript Object Notation) é uma formatação de texto leve para troca de dados entre cliente e servidor.
Além de leve, é fácil de ser lido e/ou escrito, tanto por humanos quanto por máquinas.
Outro ponto importante, é que JSON não é uma parte de Javascript (apesar de seu nome). Você pode utilizá-lo em várias outras linguagens de programação, como PHP, C++, e demais.
O media-type oficial do JSON é application/json e sua extensão é .json, isso quer dizer que você pode criar arquivos de texto contendo dados JSON [Veja mais aqui].
O formato mais simples de um arquivo JSON é:
{ "nome" : "valor" }
Onde o nome da propriedade fica no lado esquerdo, e o valor dessa propriedade no lado direito, separados por dois pontos (:).
Caso queira adicionar várias propriedades, você deve separá-las por vírgula:
{ "nome" : "Luiz Otávio", "sobrenome" : "Miranda", "hobbies" : "Desenvolver" }
Qualquer propriedade pode contém mais de um valor, no entanto, para atingir este objetivo é necessário utilizar colchetes e colocar todos os seus valores separados por vírgula.
Repare na propriedade hobbies abaixo:
{ "nome" : "Luiz Otávio", "sobrenome" : "Miranda", "hobbies" : [ "Desenvolver", "Ler", "Tocar" ] }
E você também pode complicar as coisas e aninhar milhares de informações, umas dentro de outras.
Veja hoobies agora:
{ "nome" : "Luiz Otávio", "sobrenome" : "Miranda", "hobbies" : [ { "Desenvolver" : [ "Em Javascript", "PHP" ] }, { "Ler" : [ "Tech", "Notícias" ] }, { "Beber" : "Cerveja" } ] }
Para aninhar propriedades, você utiliza um novo par de chaves e as cria dentro dessas chaves:
{ "Nome" : "Luiz Otávio", "Dados" : [ { "Desenvolver" : ["Em Javascript", "PHP"]}, { "Ler" : ["Tech", "Notícias"] }, { "Beber" : "Cerveja", "Comer" : "Churrasco" } ], "Nome2" : "Letícia", "Dados2" : [ { "Desenvolver" : "PHP" } ] }
JSON não é nada complicado, de fato, se você olhar para os trechos anteriores por alguns minutos, vai compreender como é fácil aninhar as informações que você precisa.
Esses dados JSON pode estar em qualquer tipo de arquivo, sejam eles: HTML, PHP, TXT, JSON, ou em uma variável Javascript.
var dadosJSON = { "Nome" : "Luiz Otávio", "Dados" : [ { "Desenvolver" : ["Em Javascript", "PHP"]}, { "Ler" : ["Tech", "Notícias"] }, { "Beber" : "Cerveja", "Comer" : "Churrasco" } ], "Nome2" : "Letícia", "Dados2" : [ { "Desenvolver" : "PHP" } ] };
Que, na verdade, se tornam objetos literais e podem ser acessados como tal:
var dadosJSON = { "Nome" : "Luiz Otávio", "Dados" : [ { "Desenvolver" : ["Em Javascript", "PHP"]}, { "Ler" : ["Tech", "Notícias"] }, { "Beber" : "Cerveja", "Comer" : "Churrasco" } ] }; var div = document.getElementById("texto"); div.innerHTML = 'Nome: ' + dadosJSON.Nome; div.innerHTML += '<br>Desenvolver: ' + dadosJSON.Dados[0].Desenvolver; div.innerHTML += '<br>Ler: ' + dadosJSON.Dados[1].Ler; div.innerHTML += '<br>Beber: ' + dadosJSON.Dados[2].Beber; div.innerHTML += '<br>Comer: ' + dadosJSON.Dados[2].Comer;
Perceba que à medida que você vai aninhando dados, também aumenta a complexidade para retornar esses dados. Se você ainda não percebeu, está aninhando propriedades de objetos dentro de arrays, arrays dentro de propriedades de objetos e assim por diante. Portanto, é importante que você entenda que JSON, em Javascript, é a mesma coisa que objetos literais misturados com arrays.
Quando você utiliza JSON diretamente em uma variável literal, não precisa fazer mais nada além de acessar os dados. Porém, quando eles vêm de fora (de um arquivo externo), você precisa converter esses dados em objetos utilizando duas maneiras disponíveis: eval(), que não é uma maneira segura, e JSON.parse, que é uma maneira segura, mas não é suportada por navegadores anteriores ao Internet Explorer 8.
Ajax e JSON
Normalmente, quando trabalho com JSON, estou fazendo alguma requisição utilizando Ajax (do mesmo modo que vimos na aula anterior) e tenho que pegar dados de uma base de dados, de um arquivo de configurações, ou quaisquer tipos de dados que devem ser retornados para o cliente, para fazer alguma ação.
Para nosso exemplo, e também para não entrar em contato com outras linguagens de programação, vou utilizar um arquivo que já contém as informações que desejo. Em seguida, vou carregar o conteúdo desse arquivo dentro do texto de uma DIV, apenas para que você entenda como funciona as requisições Ajax em conjunto com os dados do tipo JSON.
Organizando o meio de campo
Antes de qualquer coisa, vamos criar nosso arquivo JSON.
Para isso, simplesmente abra seu editor de textos favorito (recomendo o Notepad++) e coloque esses dados dentro dele.
Arquivo dados.json
{ "nome" : "Luiz Otávio", "sobrenome" : "Miranda", "hobbies" : [ { "Desenvolver" : [ "Em Javascript", "PHP" ] }, { "Ler" : [ "Tech", "Notícias" ] }, { "Beber" : "Cerveja" } ] }
Salve com qualquer extensão que preferir, mas, se quiser seguir o padrão, salve como "dados.json".
Agora, em nosso arquivo Javascript, vamos criar várias funções, cada uma delas para suprir uma necessidade.
Arquivo HTML (index.html)
É claro que também precisamos de um arquivo HTML com todas as tags necessárias. Creio que não preciso descrever o motivo, depois de tantas aulas que já tivemos.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Demo</title> <script src="meu_arquivo_javascript.js"></script> </head> <body> <a href="" id="a">Clique</a> <div id="texto"></div> </body> </html>
Captura / Cancela eventos
A primeira função que vamos precisar em nosso arquivo JavaScript (meu_arquivo_javascript.js), é a captura de eventos (já falamos sobre isso em "Eventos em Javascript"):
// Função para capturar eventos function capturaEventos(obj, evt, fn) { // Verifica se o objeto suporta addEventListener if(obj.addEventListener){ obj.addEventListener(evt, fn, true); } // Adiociona attachEvent da Microsoft else { var evento = 'on' + evt; obj.attachEvent(evento, fn); } }
A segunda é a função para cancelar os eventos:
// Cancela evento function cancelaEvento(evt){ // Verifica se o evento suporta stopPropagation if(evt.stopPropagation) { // Aplica-se para Firefox, Chrome e demais evt.stopPropagation(); evt.preventDefault(); } else { // Aplica-se para IEs antigos evt.cancelBubble = true; evt.returnValue = false; } }
Criando um objeto XMLHttpRequest
Agora precisamos criar uma instância do objeto XMLHttpRequest (falamos sobre isso na última aula sobre Ajax):
// Função para capturar a requisição XMLHttpRequest function verificaXmlHttp() { // Uma variável sem valor var xmlhttp; // Verifica se suporta XMLHttpRequest if (window.XMLHttpRequest) { // Adiciona o valor à variável xmlhttp = new XMLHttpRequest(); } else { // Adiciona ActiveXObject da Microsoft xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); } // Retorna o valor return xmlhttp; }
Capturando os eventos
Agora, vamos utilizar a função que criamos para capturar os eventos. O palco do show será dentro dela, onde todas as ações serão executadas:
// Captura evento load da página capturaEventos(window, 'load', function(evt){ // A ação vai ocorrer aqui });
Dentro da função anterior, vamos localizar o elemento <a> (link) na nossa página HTML, capturar o evento de clique nesse link, e, dentro do evento de clique, vamos criar nossa requisição Ajax.
// Captura evento load da página capturaEventos(window, 'load', function(evt){ // Localiza o link com id "a" var a = document.getElementById('a'); // Captura o evento de clique neste link capturaEventos(a, 'click', function(evt){ var xmlhttp = verificaXmlHttp(); // Verifica os estados da requisição xmlhttp.onreadystatechange = function(){ // Verifica se a página foi carregada corretamente if(xmlhttp.readyState === 4 && xmlhttp.status === 200) { var dadosJSON; try { dadosJSON = JSON.parse(xmlhttp.responseText); } catch(e) { eval("dadosJSON = (" + xmlhttp.responseText + ");"); } } } // Abre a requisição com o método e url xmlhttp.open('GET', 'dados.json', true); // Modifica o MimeType da requisição xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // Envia os valores xmlhttp.send(null); // Checagem para os IEs antigos var evento = evt ? evt : window.event; // Cancela o evento cancelaEvento(evento); }); });
A requisição Ajax que mostrei aqui, é a mesma que expliquei na aula anterior, porém, ao invés de fazer tudo diretamente, separei algumas partes – que são reutilizáveis – em funções separadas (também já vimos sobre funções em Javascript).
Veja a parte em que chamamos a função verificaXmlHttp() para criar a instância do objeto XMLHttpRequest:
var xmlhttp = verificaXmlHttp();
Depois que tenho a instância do objeto, posso continuar trabalhando meu código, como fizemos na aula anterior.
A parte final da função:
// Checagem para os IEs antigos var evento = evt ? evt : window.event; // Cancela o evento cancelaEvento(evento);
Serve para que a página não seja atualizada quando o usuário clicar no link. Se isso acontecer, perderemos a requisição Ajax, que está ali justamente para que a página não atualize.
A parte que vamos focar neste artigo é a seguinte:
var dadosJSON; try { dadosJSON = JSON.parse(xmlhttp.responseText); } catch(e) { eval("dadosJSON = (" + xmlhttp.responseText + ");"); }
Que acontece depois que a requisição Ajax foi processada e os dados foram retornados para a página em que o cliente está.
xmlhttp.responseText
Retorna o texto do arquivo dados.json, que é o fizemos no início dessa sessão anterior. Porém, se você tentar ver esses dados em um depurador Javascript, terá exatamente isso em uma string:
Para nós, não é interessante que os dados sejam retornados em uma string, mas sim em um objeto Javascript.
Em navegadores mais novos, basta utilizar JSON.parse, atribuir o valor a uma variável e estamos prontos, já temos nosso objeto e podemos acessar. Porém, em navegadores mais velhos, que não suportam JSON.parse, uma das maneiras de forçar uma string a se tornar um objeto é tentar utilizar eval().
Existem várias coisas a se levar em consideração ao utilizar eval(), pois, essa função avalia o texto de uma string e tenta fazer com que ela se transforme em código válido. Com isso, você já pode imaginar que se o texto da string puder ser manipulado por pessoas maliciosas, elas podem fazer o que quiserem dentro do seu código.
O conselho aqui é que você deve estudar muito bem como a sua aplicação vai funcionar, antes de utilizar essa função.
Voltando ao nosso código, quando utilizamos:
var dadosJSON; try { dadosJSON = JSON.parse(xmlhttp.responseText); } catch(e) { eval("dadosJSON = (" + xmlhttp.responseText + ");"); }
Verificamos se a primeira parte do código funciona no navegador em que está sendo executada:
dadosJSON = JSON.parse(xmlhttp.responseText);
Se o código acima não funcionar, outro trecho é passado:
eval("dadosJSON = (" + xmlhttp.responseText + ");");
A primeira parte é para navegadores mais novos, a segunda vai funcionar com versões antigas do IE6 e 7, e as outras versões que não suportam JSON.parse.
Depois que você tem o objeto, pode acessar os dados como preferir.
Normalmente, desenvolvedores não sabem quais valores virão nos seus dados JSON, e você não precisa limitar sua aplicação se não souber.
Apesar de todos os níveis do nosso arquivo JSON, podemos ainda utilizar um laço for … in para acessar os valores de maneira automática:
// Localiza nossa div dentro do HTML var div = document.getElementById('texto'); // Utiliza um laço for ... in for( var propriedade in dadosJSON ){ // Adiciona a propriedade no texto da div div.innerHTML += propriedade + ' = '; // Verifica se a propriedade é um objeto if (typeof dadosJSON[propriedade] !== 'object') { // Adiciona o valor da propriedade no texto da div div.innerHTML += dadosJSON[propriedade] + '<br>'; } else { // Se for objeto, acessa o valor da maneira alterativa e // adiciona na div div.innerHTML += '<br>'; div.innerHTML += 'Desenvolver: ' + dadosJSON[propriedade][0].Desenvolver; div.innerHTML += '<br>'; div.innerHTML += 'Ler: ' + dadosJSON[propriedade][1].Ler; div.innerHTML += '<br>'; div.innerHTML += 'Beber: ' + dadosJSON[propriedade][2].Beber; } }
Já falamos sobre este tipo de laço em nosso artigo "Laços em Javascript", mesmo assim, perca um tempinho lendo os comentários que deixo em todos os trechos de código dessa página, eles podem ajudar no seu entendimento.
Javascript completo
Caso você tenha se perdido no código, segue abaixo o Javascript completo utilizado nessa aula:
// Função para capturar eventos function capturaEventos(obj, evt, fn) { // Verifica se o objeto suporta addEventListener if(obj.addEventListener){ obj.addEventListener(evt, fn, true); } // Adiociona attachEvent da Microsoft else { var evento = 'on' + evt; obj.attachEvent(evento, fn); } } // Cancela evento function cancelaEvento(evt){ // Verifica se o evento suporta stopPropagation if(evt.stopPropagation) { // Aplica-se para Firefox, Chrome e demais evt.stopPropagation(); evt.preventDefault(); } else { // Aplica-se para IEs antigos evt.cancelBubble = true; evt.returnValue = false; } } // Função para capturar a requisição XMLHttpRequest function verificaXmlHttp() { // Uma variável sem valor var xmlhttp; // Verifica se suporta XMLHttpRequest if (window.XMLHttpRequest) { // Adiciona o valor à variável xmlhttp = new XMLHttpRequest(); } else { // Adiciona ActiveXObject da Microsoft xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); } // Retorna o valor return xmlhttp; } // Captura evento load da página capturaEventos(window, 'load', function(evt){ // Localiza o link com id "a" var a = document.getElementById('a'); // Captura o evento de clique neste link capturaEventos(a, 'click', function(evt){ var xmlhttp = verificaXmlHttp(); // Verifica os estados da requisição xmlhttp.onreadystatechange = function(){ // Verifica se a página foi carregada corretamente if(xmlhttp.readyState === 4 && xmlhttp.status === 200) { var dadosJSON; try { dadosJSON = JSON.parse(xmlhttp.responseText); } catch(e) { eval("dadosJSON = (" + xmlhttp.responseText + ");"); } // Localiza nossa div dentro do HTML var div = document.getElementById('texto'); // Utiliza um laço for ... in for( var propriedade in dadosJSON ){ // Adiciona a propriedade no texto da div div.innerHTML += propriedade + ' = '; // Verifica se a propriedade é um objeto if (typeof dadosJSON[propriedade] !== 'object') { // Adiciona o valor da propriedade no texto da div div.innerHTML += dadosJSON[propriedade] + '<br>'; } else { // Se for objeto, acessa o valor da maneira alterativa e // adiciona na div div.innerHTML += '<br>'; div.innerHTML += 'Desenvolver: ' + dadosJSON[propriedade][0].Desenvolver; div.innerHTML += '<br>'; div.innerHTML += 'Ler: ' + dadosJSON[propriedade][1].Ler; div.innerHTML += '<br>'; div.innerHTML += 'Beber: ' + dadosJSON[propriedade][2].Beber; } } } } // Abre a requisição com o método e url xmlhttp.open('GET', 'dados.json', true); // Modifica o MimeType da requisição xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // Envia os valores xmlhttp.send(null); // Checagem para os IEs antigos var evento = evt ? evt : window.event; // Cancela o evento cancelaEvento(evento); }); });
Isso mesmo, 102 linhas de puro Javascript só para capturar um clique e executar uma requisição Ajax!
Download
Você também pode baixar os arquivos utilizados nessa aula no link abaixo:
- Download: Ajax e JSON utilizando Javascript puro
Concluindo
De início, pode parecer extremamente complicado trabalhar com Ajax e JSON, principalmente quando os dados são aninhados em várias camadas. No entanto, você só vai aprender se "quebrar" um pouco a cabeça para tentar resolver possíveis problemas que poderão ocorrer na sua aplicação.
Qualquer dúvida, basta perguntar nos comentários.
Outras aulas
Caso tenha perdido a aula anterior, segue o link:
Caso queira visualizar todas as aulas dessa sessão em ordem cronológica invertida: