Universidade Federal de Uberlândia Faculdade de Computação Programação para Internet Módulo 9 Web Dinâmica Introdução ao AJAX Prof. Dr. Daniel A. Furtado
AJAX Introdução AJAX = Asynchronous JavaScript and XML; Não é uma linguagem de programação; É uma técnica utilizada para criar websites rápidos e dinâmicos; Possibilita trocar dados com o servidor e atualizar partes de uma página web sem precisar recarregar a página inteira; Com AJAX, a comunicação com o servidor pode ser realizada de forma assíncrona (em segundo plano), sem interromper as funcionalidades da página corrente; AJAX utiliza uma combinação de tecnologias: Objeto XMLHttpRequest, do browser (para requisitar dados/serviço ao servidor) JavaScript e HTML DOM (para mostrar ou utilizar os dados) CSS, XML, JSON (formato para transferência de dados) Ref: adaptado de w3schools.com 2
AJAX Exemplos de Aplicações A tecnologia é amplamente utilizada (até mesmo por empresas e serviços de renome como Google Maps, Gmail, YouTube e Facebook); Por exemplo, pode-se utilizar AJAX para realizar o preenchimento automático dos campos de endereço em um formulário Web assim que o usuário informar o CEP; Outros exemplos: Sugestões de buscas no Google Ao buscar um modelo de carro na tabela FIPE, os modelos são carregados, em segundo plano, após seleção do fabricante. Ref: adaptado de w3schools.com 3
4 Como AJAX Funciona 1. Ocorre um evento na página web (página carregada, botão pressionado, opção selecionada, etc.); 2. Cria-se um objeto XMLHttpRequest utilizando JavaScript; 3. Utiliza-se o objeto para enviar uma requisição HTTP ao servidor; 4. O servidor Web processa a requisição (enquanto isso, a página Web no cliente fica livre para executar outras operações*); 5. O servidor envia uma resposta de volta para a página Web; 6. A resposta é lida pela página utilizando JavaScript e uma ação apropriada é então executada (como atualização da página, apresentação de informação detalhada, etc.) *No caso da requisição ser assíncrona Ref: adaptado de w3schools.com
Como AJAX Funciona Ref: adaptado de w3schools.com 5
Requisição Síncrona x Assíncrona Na prática, a maior parte das requisições AJAX é realizada de maneira assíncrona. Porém, também é possível realizá-la de forma síncrona. Requisição Síncrona A função JavaScript que inicia a requisição ficará bloqueada, aguardando pela resposta do servidor; Não é possível executar nenhum outro código JavaScript enquanto a requisição estiver sendo processada no servidor. Requisição Assíncrona A função JavaScript prossegue com sua execução enquanto a requisição é tratada em segundo plano. Isto significa que é possível executar outras operações com JavaScript enquanto o servidor processa a requisição; O andamento da requisição pode ser acompanhado no JavaScript por meio de eventos, sendo possível executar uma ação assim que a requisição terminar. 6
<script> Exemplo de Requisição Assíncrona - Método GET // cria uma instância do XMLHttpRequest para iniciar a requisição AJAX var xmlhttp = new XMLHttpRequest(); // configura o método da requisição, a URL do recurso ou serviço e true para requisição assíncrona xmlhttp.open("get", "ARQUIVO_OU_URL_DO_SERVICO", true); // indica a função que será executada quando a requisição encerrar xmlhttp.onload = function () { if (xmlhttp.status == 200) }; { // Coloque aqui as operações necessárias para tratar o resultado // da requisição quando finalizada com sucesso document.getelementbyid("demo").innerhtml = xmlhttp.responsetext; } else { // Ocorreu alguma falha no processamento da requisição e o servidor // retornou um código de status diferente de '200 Ok'. // Coloque o tratamento de erro aqui. alert("ocorreu um erro ao processar a requisição: " + xmlhttp.status + xmlhttp.responsetext); } // indica a função a ser executada caso ocorra uma falha na comunicação com o servidor xmlhttp.onerror = function () { alert("ocorreu um erro ao processar a requisição"); }; // envia a requisição xmlhttp.send(); </script> 7
8 Exercício 1 Testar e estudar os arquivos anexos do Exemplo1: 1. Envie os arquivos para o servidor do Awardspace; 2. Acesse o arquivo testeajax.html digitando a URL adequadamente no navegador; 3. Analise o código fonte dos arquivos testeajax.html e conteudoadicional.txt; 4. Observe que o conteúdo do arquivo.txt é carregado dinamicamente na página testeajax.html utilizando uma requisição assíncrona com AJAX; 5. No arquivo testeajax.html, observe que o resultado da requisição é acessado por meio de xmlhttp.responsetext;
Exercício 2 Testar e estudar os arquivos anexos do Exemplo2A: 1. Envie os arquivos para o servidor do Awardspace; 2. Acesse o arquivo busca.html digitando a URL adequadamente no navegador. Informe uma letra no campo de busca da página e observe a resposta; 3. Analise o código fonte dos arquivos busca.html e buscasugestao.php; 4. Observe que o script buscasugestao.php recebe um parâmetro de busca pela URL e procura por nomes no vetor de nomes que começam com a letra informada. Observe que o script produz uma string de nomes como resultado, a qual é recebida e apresentada na página busca.html utilizando JavaScript. 9
10 xmlhttp.onload - Observações No exemplos apresentados anteriormente, existe a possibilidade da condição (xmlhttp.status == 200) ser verdadeira mesmo quando o script PHP termina com erros; Isto acontece porque o Apache/PHP retorna automaticamente o código de status padrão 200, independentemente do script PHP encerrar com sucesso ou falha. Portanto, o desenvolvedor precisa tomar medidas para tratar essa situação, evitando que o usuário final visualize mensagens detalhadas de erros no servidor;
Exercício 3 Simular um erro PHP no exemplo Exemplo2A: 1. Abra o arquivo buscasugestao.php e troque o if na linha 22 por se ; 2. Salve o arquivo e reenvie para o Awardspace; 3. Acesse novamente o arquivo busca.html pelo navegador, digite uma letra no campo de busca e observe o resultado. 11
<script> xmlhttp.onload - Observações O Exemplo 2B é uma alteração do Exemplo 1A visando tratar melhor a resposta do servidor. Foram feitas basicamente duas alterações: 1. O script buscasugestoes.php produz uma resposta válida iniciando com a string OK ; 2. O arquivo busca.html adiciona uma condição para verificar se a resposta produzida pelo servidor começa com os caracteres OK ; // indica a função que será executada quando a requisição encerrar xmlhttp.onload = function () { // ------------------- NOVIDADE DESDE EXEMPLO ------------------------------ // A segunda condição deste if foi inserida como uma forma de verificar // se o script no servidor realmente foi finalizado com sucesso e produziu // uma resposta válida. Caso ocorram erros ou warnings antes da geração do resultado, // tais mensagens serão enviadas (e a resposta produzida não começará com "OK") // ------------------------------------------------------------------------- if (xmlhttp.status == 200 && xmlhttp.responsetext.substring(0, 2) == "OK") { // Coloque aqui as operações necessárias para tratar o resultado // da requisição quando finalizada com sucesso document.getelementbyid("demo").innerhtml = xmlhttp.responsetext; } else { // Ocorreu alguma falha no processamento da requisição e o servidor // retornou um código de status diferente de '200 Ok'. // Coloque o tratamento de erro aqui. alert("ocorreu um erro ao processar a requisição: " + xmlhttp.status + xmlhttp.responsetext); } }; 12
Exercício 4 Simular um erro PHP no exemplo Exemplo2B: 1. Abra o arquivo buscasugestao.php e troque o if na linha 22 por se ; 2. Salve o arquivo e reenvie para o Awardspace; 3. Acesse novamente o arquivo busca.html pelo navegador, digite uma letra no campo de busca e observe o resultado. 13
AJAX Exemplo 3 Outra Forma Nos exemplos anteriores utilizamos a propriedade onload do objeto XMLHttpRequest para indicar uma função de callback que deve ser executada quando a requisição finalizar. Uma outra possibilidade é monitorar o valor da propriedade readystate desse objeto. A propriedade muda de valor à medida em que a requisição é criada e tratada. Quando a requisição é finalizada e a resposta está pronta, readystate muda para o valor 4. Isto é ilustrado a seguir:... var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readystate == 4 && xmlhttp.status == 200) { // processar a resposta do servidor } } xmlhttp.open(...); xmlhttp.send();... Programação para Internet 14 Prof. Dr. Daniel A. Furtado
Resumo das Propriedades do Objeto XMLHttpRequest Propriedade Descrição onreadystatechange Utilizado para indicar a função a ser chamada quando a propriedade readystate muda de valor readystate Mantém o estado da requisição: 0: requisição não iniciada 1: conexão com o servidor estabelecida 2: requisição recebida pelo servidor 3: requisição em processamento 4: requisição finalizada e resposta pronta responsetext responsexml status statustext Permite acessar os dados retornados na forma textual Permite acessar os dados retornados no formato XML Retorna o status-number da requisição: 200: "OK" 403: "Forbidden" 404: "Not Found" Para a lista completa acesse Http Messages Reference Retorna o status-text (isto é, "OK" ou "Not Found") Adaptado de W3Schools.com 15
Resumo dos Métodos do Objeto XMLHttpRequest Método new XMLHttpRequest() Descrição Cria um novo objeto XMLHttpRequest open(method,url,async) send() send(string) setrequestheader() Configura a requisição, onde: method: método de requisição HTTP: GET, POST, PUT, DELETE, etc. url: local do arquivo no servidor async: true (assíncrono) ou false (síncrono) Envia a requisição para o servidor Usado para requisições GET Envia a requisição para o servidor Usado para requisições POST Adiciona um par rótulo/valor ao cabeçalho da requisição para ser enviado O arquivo pode ser de qualquer tipo, como.txt,.xml ou um arquivo de script, como.php ou.asp, o qual pode executar ações no servidor antes de enviar uma resposta de volta. Adaptado de W3Schools.com 16
Enviando dados com AJAX: GET x POST Nos exemplos anteriores utilizamos o método GET para efetuar a requisição e passar parâmetros para o script no servidor. Neste caso, os valores podem ser passados no momento da chamada do método open, como ilustrado a seguir: xhttp.open("get", "teste.php?primeironome=henry&ultimonome=ford", true); xhttp.send(); Entretanto, esses dados também poderiam ser enviados pelo método POST. Isto é apresentado no exemplo a seguir. xhttp.open("post", "teste.php", true); xhttp.setrequestheader("content-type", "application/x-www-form-urlencoded"); xhttp.send("primeironome=henry&ultimonome=ford"); application/x-www-form-urlencoded é um tipo MIME. Para mais informações, acesse https://developer.mozilla.org/en-us/docs/web/http/basics_of_http/mime_types Ref: adaptado de w3schools.com 17
JSON JavaScript Object Notation 18
19 Relembrando: Objetos Simples em JavaScript Objetos simples em JavaScript (PlainObject) podem ser utilizados para armazenar uma coleção de propriedades de entidades do mundo real; Tais objetos podem ser definidos por meio de uma lista de pares do tipo nomedapropriedade : valor, separados por vírgula e colocados entre chaves. O nome da propriedade pode aparecer com ou sem aspas; Exemplo: var pessoa = { pnome:"john", unome:"doe", idade:50, eyecolor:"blue" }; alert(pessoa.pnome); // acessa a propriedade pnome do objeto pessoa alert(pessoa.idade); // acessa a propriedade idade do objeto pessoa Ref: adaptado de w3schools.com
JSON Introdução JSON é um acrônimo para JavaScript Object Notation; JSON é um formato para intercâmbio de dados, baseado em texto, cuja notação é derivada da notação de objetos em JavaScript; Por ser textual, é independente de linguagem; JSON para intercâmbio de dados entre cliente e servidor: Como JSON é baseado em texto, pode-se converter um objeto JavaScript para JSON e então enviá-lo ao servidor; Também é possível receber do servidor uma string de dados no formato JSON e convertê-la para um objeto JavaScript; Dessa forma, os dados podem ser convertidos diretamente em objetos JavaScript, sem a necessidade de executar procedimentos complexos para processamento do texto e extração dos dados. Ref: adaptado de w3schools.com 20
21 JSON - Sintaxe A sintaxe do formato JSON é derivada da notação de objetos em JavaScript: Os dados são organizados em pares (nome : valor), separados por vírgula; Objetos são colocados entre chaves; Vetores são colocados entre colchetes. Em JSON, os nomes das propriedades (keys) devem ser strings colocadas sempre entre aspas duplas*; { "nome":"elon", "sobrenome":"musk", "idade": 45 } *Em JavaScript os nomes das propriedades podem aparecer com ou sem aspas. Ref: adaptado de w3schools.com
22 JSON Objetos Complexos JSON possibilita a representação de objetos complexos, formados por vetores e outros objetos. Exemplos: { } "name": "John", "age": 30, "cars": [ "Ford", "BMW", "Fiat" ] { } "name": "John", "age": 30, "cars": [ { "name":"ford", "models":[ "Fiesta", "Focus", "Mustang" ] }, { "name":"bmw", "models":[ "320", "X3", "X5" ] }, { "name":"fiat", "models":[ "500", "Panda" ] } ] Ref: adaptado de w3schools.com
Recebendo dados JSON do servidor Objetos em PHP podem ser convertidos para o formato JSON por meio da função json_encode Uma string JSON é convertida para um objeto JavaScript por meio do método JSON.parse Código no servidor (PHP) <?php $myobj->name = "John"; $myobj->age = 30; $myobj->city = "New York"; $myjson = json_encode($myobj); echo $myjson;?> Código no cliente (JavaScript) var xmlhttp = new XMLHttpRequest(); xmlhttp.onload = function() { var myobj = JSON.parse(this.responseText); var div = document.getelementbyid("demo"); div.innerhtml = myobj.name; }; xmlhttp.open("get", "demo_file.php", true); xmlhttp.send(); OBS: Arrays em PHP também podem ser convertidos para JSON. Veja exemplo em https://www.w3schools.com/js/js_json_php.asp IMPORTANTE: a função json_encode do PHP exige que todas as strings no objeto sejam codificadas como UTF-8. Caso o objeto contenha algum campo com caracteres especiais não codificados em UTF-8 (isso pode acontecer dependendo das configurações do MySQL, por exemplo), a string JSON não será gerada e a função retornará false. Adaptado de W3Schools.com 23
24 Exercício 5 Testar e estudar os arquivos anexos do Exemplo3: 1. Abra o arquivo conexaomysql.php e informe adequadamente os dados para conexão com o MySQL (Awardspace); 2. Crie uma tabela no banco de dados com o nome Endereco contendo os campos CEP, Rua, Bairro e Cidade: CREATE TABLE Endereco ( Cep varchar(11), Rua varchar(50), Bairro varchar(50), Cidade varchar(50) ) 3. Insira alguns registros na tabela utilizando a linguagem SQL; INSERT INTO Endereco VALUES ("38400-100", "Joao Naves", "Santa Monica", "Uberlandia"); 4. Envie os arquivos do exemplo para o servidor e acesse o arquivo endereco.html. Informe no campo CEP um dos números de CEP que você inseriu na tabela Endereco; 5. Analise o código fonte dos arquivos endereco.html e buscaendereco.php;
AJAX com JQuery 25
Utilizando AJAX por meio da biblioteca jquery Uma outra maneira de efetuar uma requisição AJAX é utilizando o método $.ajax da biblioteca jquery: $.ajax({ url: /* endereco do arquivo no servidor, entre aspas */, type: /* método de envio: GET, POST, PUT ou DELETE, entre aspas */, async: /* true para assíncrona ou false para síncrona */, datatype: /* o tipo dos dados esperados como resposta do servidor pode ser xml, json, script ou html */, data: /* dados a serem enviados: objeto JavaScript, string ou array */, success: function(result) { }, // Tratar aqui a resposta do servidor // quando a requisição é finalizada com sucesso. // Processar os dados recebidos // É RECOMENDADO CONFIRMAR O SUCESSO, pois em alguns casos // o script no servidor pode encerrar notificando sucesso mesmo // na presença de erros, como em casos de erros de sintaxe de código, por exemplo. // (veja mais detalhes no arquivo Ex-04-endereco.html). error: function(xhr, status, error) { } }); // tratar aqui quando ocorrer um erro alert(status + error + xhr.responsetext); 26
27 AJAX com jquery Testar e analisar cuidadosamente os exemplos anexos: Exemplo4 Exemplo5
28 Método $.load $(selector).load(url,data,callback); $("#div1").load("demo_test.txt");
Referências www.w3schools.com/ajax api.jquery.com/jquery.ajax/ 29