O AJAX é uma ferramenta essencial no desenvolvimento moderno de aplicativos da web. Ele permite enviar e receber dados de forma assíncrona para o servidor e depois analisá -los no JavaScript. Ajax é a abreviação de JavaScript assíncrono e XML (JavaScript assíncrono e XML).
O nome da especificação do núcleo do Ajax é herdado do objeto JavaScript usado para criar e iniciar solicitações: xmlHttPrequest. Existem dois níveis dessa especificação. Todos os navegadores convencionais implementam o primeiro nível, que representa o nível básico de funcionalidade. O segundo nível estende a especificação inicial, incorpora eventos adicionais e alguns recursos para facilitar a colaboração com os elementos do formulário e suporta algumas especificações relacionadas.
1. Ajax começa
A chave do Ajax está no objeto xmlHttPrequest, e a maneira de entender esse objeto é olhar para um exemplo. O código a seguir mostra o uso simples do objeto xmlHttPrequest:
<! Doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title> Exemplo </title> </head> <body> <div> <butão> Apples </button> "Targetries </button> <butão> BOTTONAS </////Div </Div> <butge>" Tarreries <butries> "Prostring> Button> </////button> </div> <but>" TONTRES "" Pressione </button> </Div </div> <butt> "Target>" Tarreries </Button> <botão> <botão> </////button> </div> <but> "TONTRES" " type = "Application/javaScript"> vartons var = document.getElementsByTagName ("Button"); for (var i = 0; i <botões.length; i ++) {botões [i] .OnClick = handleButtonPress; } // O script chamará esta função para responder à função de evento de clique do Button Control (e) {// criar um novo objeto xmlHttPrequest var httprequest = novo xmlHttPrequest (); // Defina um manipulador de eventos para o evento ONREADESTATECHANGE HTTPREQUEST.ONREADESTATECHANGE = HandleResponse; // Use o método aberto para especificar o método HTTP e o URL para solicitar (ou seja, diga ao objeto HttPrequest o que você deseja fazer) httprequest.open ("get", e.target.innerhtml+". Html"); // Nenhum dado é enviado ao servidor aqui, portanto, o método de envio não possui parâmetros disponíveis httprequest.send (); } // Processando a resposta // Depois que o script chamar o método de envio, o navegador enviará uma solicitação ao servidor em segundo plano. Como a solicitação é processada em segundo plano, o Ajax conta com eventos para informar o progresso da solicitação. Função HandleSponse (e) {// Quando o evento OnreadyStateChange for acionado, o navegador passará um objeto de evento para a função manipuladora especificada e a propriedade de destino será definida como xmlHttPrequest associada a este evento se (e.target.readystate == xmlHtTrequest.Done &. Document.getElementById ("Target"). Innerhtml = e.target.ResponsEtext; // Mostra o conteúdo do documento solicitado}} </script> </body> </html>Três documentação adicional é muito simples:
<! Doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title> Apples </title> <style> img {float: esquerda; preenchimento: 2px; margem: 5px; border: médio duplo; cor de fundo: lâmpada: luz; Largura: 100px; Altura: 100px;} </style> </head> <body> <p> <img src = "../ img/show-page/img_apples.jpg"/> página para maçãs.O efeito é mostrado na figura abaixo:
À medida que o usuário clica em cada botão de fruta, o navegador executa de forma assíncrona e recupera o documento solicitado, enquanto o documento principal não está recarregado. Este é o comportamento típico do Ajax.
2. Usando eventos Ajax
Depois de criar e explorar um exemplo simples, você pode começar a procurar os recursos suportados pelo objeto XMLHTTPREQUEST e como usá -los em sua solicitação. O ponto de partida são os eventos adicionais definidos na especificação de segundo nível:
A maioria desses eventos é acionada em um momento específico durante a solicitação. Os dois eventos são exceções, ReadyStatechange e Progress, que podem ser acionados várias vezes para fornecer atualizações de progresso.
Quando esses eventos são agendados, o navegador usa um objeto de evento regular para o evento ReadyStateChange e um objeto ProgressEvent para outros eventos. O objeto ProgressEvent define todos os membros do objeto de evento e adiciona estes membros descritos na figura a seguir:
O código a seguir mostra como usar esses eventos:
<! Doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title> exemplo </title> <yoy> tabela {margem: 10px; colapso de borda: colapso; float: esquerda;} div {margin: 10px;} td, th {preenchimento: 4px;} </style> </ad Head> <body> <div> <but uma button> Apples </button> button> cereries </button> <butt> bananas </button> </div </table> "eventries </tabela> </tabela> <butt> <butt> bananas </button> </div =" eventries "</tabela> </tabela> <butt> <butt> type = "Application/javaScript"> vartons var = document.getElementsByTagName ("Button"); for (var i = 0; i <botões.length; i ++) {botões [i] .OnClick = handleButtonPress; } var httprequest; Função HODEBTOTTONpress (e) {ClearEventDetails (); httprequest = novo xmlHttPrequest (); httprequest.onReadyStatechange = HandleResponse; httprequest.onerror = handleError; httprequest.onload = handleload ;; httprequest.onLoadend = handleLoadend; httprequest.onloadstart = handleloadstart ;; httprequest.onProgress = handleProgress; httprequest.open ("get", e.target.innerhtml+". html"); httprequest.send (); } função handleSponse (e) {displayEventDetails ("ReadyState ("+httPrequest.readyState+")") se (e.target.readyState == xmlhttPreQuest.Done && e.target.status == 200) {document.OnMementBy. "Target && e.Target.status == 200) {document.hemOnMentBy. }} function handleError (e) {displayEventDetails ("error", e);} função handleLoad (e) {displayEventDetails ("load", e);} função handleLoadend (e) {displayEventDetails ("carregamento", e);} função handloadnd. função handleloadstart (e) {displayEventDetails ("loadStart", e);} função manipulamento (e) {displayEventDetails ("progresso", e);} função clearEventDetails () {document.getElementbyid ("eventos). "<tr> <th> evento </th> <th> comprimento Computable </th> <th> carregado </th> <th> total </th>"; } função displayEventDetails (eventName, e) {if (e) {document.getElementById ("events"). innerhtml+= "<tr> <td>"+eventname+"</td> <td>"+e.lengthcomputable+"</td> <td>" td> e.. E.Total+"</td> </tr>"; } else {document.getElementById ("events"). innerhtml+= "<tr> <td>"+eventname+"</td> <td> na </td> <td> na </td> <td> na </td> <td> na </td> </td>; }} </script> </body> </html>Esta é uma variação do exemplo anterior, registrando um manipulador para alguns eventos e criando um registro para cada evento processado em um elemento de tabela. A partir da imagem a seguir, você pode ver como o navegador Firefox desencadeia esses eventos.
3. Lidar com erros
Dois tipos de erros devem receber atenção ao usar o Ajax. A diferença entre eles decorre de diferentes perspectivas.
O primeiro tipo de erro é um problema visto da perspectiva do objeto xmlHttPrequest: alguns fatores impedem que a solicitação seja enviada para o servidor. Por exemplo, o DNS não pode resolver o nome do host, a solicitação de conexão é negada ou o URL é inválido.
O segundo tipo de problema é o problema visto da perspectiva do aplicativo, não o objeto xmlHttPrequest. Eles ocorrem quando a solicitação é enviada com sucesso ao servidor, que recebe a solicitação, processa e gera uma resposta, mas a resposta não aponta para o que você espera. Por exemplo, se o URL solicitado não existir, esse tipo de problema ocorre.
Existem três maneiras de lidar com esses erros, conforme mostrado no código a seguir:
3.1 Erros de configuração de manuseio
O primeiro tipo de problema que precisa ser tratado é passar dados incorretos para o objeto xmlHttPresquest, como uma URL incorreta. Eles são extremamente propensos a ocorrer ao gerar URLs com base na entrada do usuário. Para simular esse tipo de problema, o documento acima possui um botão que adiciona uma tag URL ruim (URL errado). Pressionar este botão chamará o método aberto na seguinte forma:
httprequest.open ("Get", "http: //")
Este é um erro que impede que a solicitação seja executada e um erro é lançado quando um evento como esse ocorre no objeto XMLHTTPREQUEST. Isso significa que é necessária uma declaração ... Catch ...
tente {... httprequest.open ("get", "http: //") ... httprequest.send (); } catch (error) {DisplayerRormsg ("Try/Catch", Error.message)}A cláusula de captura oferece a chance de se recuperar do erro. Você pode optar por solicitar ao usuário um valor ou voltar ao URL padrão ou simplesmente descartar a solicitação. Neste exemplo, a função DisplayerRormSG é chamada para exibir a mensagem de erro.
3.2 Erros de solicitação de processamento
O segundo tipo de erro ocorre quando a solicitação foi gerada, mas existem outros erros. Para simular esse tipo de problema, um botão rotulado como host ruim (host de erro) foi adicionado no exemplo. Quando este botão for pressionado, o método aberto será chamado para acessar um URL indisponível:
httprequest.open ("Get", http: //www.ycdoitt.com/nopage.html)Existem dois problemas com este URL. O primeiro problema é que o nome do host não pode ser resolvido pelo DNS, para que o navegador não possa gerar uma conexão do servidor. Esse problema sabe que o objeto xmlHttPrequest só se torna óbvio quando começa a gerar a solicitação, por isso sinaliza erros de duas maneiras. Se você registrar um ouvinte para um evento de erro, o navegador enviará um objeto de evento para o seu ouvinte. Aqui estão as funções usadas no exemplo:
function handleerror (e) {displayerRormsg ("Evento de erro", httprequest.status + httprequest.statustustext); }Quando esses erros ocorrem, o grau de informação que pode ser obtido no objeto xmlHttPrequest depende do navegador. Infelizmente, na maioria dos casos, o status com um valor de 0 e um valor em branco Statustext será obtido.
O segundo problema é que o URL e a solicitação gerada têm fontes diferentes, o que não é permitido por padrão. Normalmente, você só pode enviar solicitações AJAX para o URL da mesma origem que carrega o script. Quando um navegador relata esse problema, um erro pode ser lançado ou um evento de erro pode ser acionado. Os navegadores diferentes lidam com isso de maneira diferente. Os navegadores diferentes também verificam a fonte em diferentes momentos, o que significa que o navegador nem sempre pode ser visto destacando o mesmo problema. O compartilhamento de recursos de origem cruzada pode ser usada para ignorar restrições homólogas.
3.3 Manipulação de erros de aplicativos
O último tipo de erro ocorre quando a solicitação é concluída com êxito (da perspectiva do objeto XmlHttPrequest), mas não retorna os dados que você deseja. Para criar esses problemas, adicione um botão com o pepino do rótulo no exemplo acima. Pressionar este botão gerará um URL de solicitação semelhante às maçãs, cerejas e botões de bananas, mas o documento Cucumber.html não existe no servidor.
Não há erro nesse processo em si (porque a solicitação foi concluída) e é necessário determinar o que está acontecendo com base no atributo de status. Ao solicitar um documento existente, o código de status 404 será obtido, o que significa que o servidor não pode encontrar o documento solicitado. Você pode ver como o exemplo lida com códigos de status diferentes de 200 (significando ok):
if (httprequest.status == 200) {Target.innerhtml = httprequest.ResponsEtext; } else {document.getElementById ("statusmsg"). innerhtml = "status:" + httprequest.status + "" + httprequest.statustext; }Neste exemplo, os valores de status e statustext são simplesmente exibidos. Em aplicativos reais, a recuperação precisa ser realizada de maneira útil e significativa (como exibir conteúdo alternativo ou alertar os usuários de que há um problema, dependendo de qual é mais adequado para o aplicativo).
4. Obtenha e defina cabeçalhos
Usando o objeto XMLHTTPREQUEST, você pode definir o cabeçalho da solicitação enviado para o servidor e o cabeçalho na resposta do servidor.
4.1 Subscite o método HTTP para solicitações
Geralmente não é necessário adicionar ou modificar o cabeçalho na solicitação AJAX. O navegador sabe o que enviar e o servidor sabe como responder. No entanto, existem várias exceções. O primeiro é o cabeçalho X-HTTP-Metod-Override.
O padrão HTTP é frequentemente usado para solicitar e transmitir documentos HTML na Internet e define muitos métodos. A maioria das pessoas sabe sobre obter e postar porque é a mais usada. No entanto, existem outros métodos (incluindo put e exclusão) que são usados para dar sentido ao URL solicitado ao servidor, e esse uso está em ascensão. Por exemplo, se você deseja visualizar um registro de usuário, poderá gerar tal solicitação:
httprequest.open ("get", "http: // myserver/registros/freeman/adam");Somente o método HTTP e o URL solicitado são exibidos aqui. Para que essa solicitação funcione sem problemas, o lado do servidor deve ser capaz de entender a solicitação pelo aplicativo e convertê -lo em uma peça de dados adequada para ser enviada de volta ao servidor. Se você deseja excluir os dados, pode escrevê -los assim:
httprequest.open (" delete ", "http: // myserver/registros/freeman/adam");A chave aqui é expressar o que você deseja que o servidor faça via HTTP, em vez de codificá -lo no URL de alguma forma.
O problema do uso dos métodos HTTP dessa maneira é que muitas tecnologias da Web convencionais suportam apenas o Get and Post, e muitos firewalls permitem que o GET e POST solicitações passe. Existe uma abordagem idiomática para evitar essa limitação, que deve usar o cabeçalho X-HTTP-Metod-Override para especificar o método HTTP que você deseja usar, mas o formulário é comercializado e enviando uma solicitação de postagem. A demonstração do código é a seguinte:
<! Doctype html> <html lang = "pt"> <head> <meta charset = "utf-8"> <title> Exemplo </titit> </ad Head> <body> <div> <butão> Apples </button> "TONTRES" "TONTRES </BOTTLEBTON> </Div </Div> <butbot>" Tarreries </button> button> <////button> </div> <butge> "Target>" Totbot> "TONTRES" "PROMPLOT> <//button> </div> <div>" Target> "Totbot>" TONTREI "" document.getElementsByTagName ("Button"); for (var i = 0; i <botões.length; i ++) {botões [i] .OnClick = handleButtonPress; } var httprequest; Função HODEBTOTTONpress (e) {httPrequest = new XmlHttPrequest (); httprequest.onReadyStatechange = HandleResponse; httprequest.open ("get", e.target.innerhtml+". html"); httprequest.setRequestHeader ("x-http-method-override", "delete"); httprequest.send (); } function handleError (e) {DisplayerRormsg ("Evento de erro", httprequest.status+httprequest.statustext); } function handleSponse () {if (httprequest.readyState == 4 && httprequest.status == 200) {document.getElementById ("Target"). innerhtml = httprequest.ResponseTxt; }} </script> </body> </html>Neste exemplo, o método setRequestHeader no objeto xmlHttPrequest é usado para indicar que a solicitação deve ser processada na forma de um método de exclusão http. Observe que eu defini este cabeçalho somente depois de chamar o método aberto. Se você tentar usar o método setRequestHeader antes do método aberto, o objeto xmlHttPrequest lança um erro.
PS: A substituição do HTTP requer a estrutura de aplicativos da Web do servidor para entender a convenção do x-http-method-override, e seu aplicativo do lado do servidor deve ser definido para encontrar e entender esses métodos menos HTTP.
4.2 Desativar o cache de conteúdo
O segundo cabeçalho útil que pode ser adicionado às solicitações de Ajax é o controle de cache, o que é especialmente útil ao escrever e depurar scripts. Alguns navegadores de cache de conteúdo de cache obtidos através de solicitações do AJAX e não o solicitarão novamente durante a sessão de navegação. Para o exemplo anterior, significa que as alterações no Apples.html, Cherries.html e Bananas.html não serão imediatamente refletidas no navegador. O código a seguir mostra como definir cabeçalhos para evitar isso:
httprequest = novo xmlHttPrequest (); httprequest.onReadyStatechange = HandleResponse; httprequest.open ("get", e.target.innerhtml+". html"); httprequest.setRequestHeader ("Cache-Control", "No-Cache"); httprequest.send ();A maneira de definir o cabeçalho é a mesma do exemplo anterior, mas desta vez o cabeçalho é o controle de cache e o valor desejado é sem cache. Depois de colocar essa declaração, se o conteúdo solicitado por meio de alterações no AJAX, ele será refletido na próxima vez que o documento for solicitado.
4.3 Leia o cabeçalho da resposta
O cabeçalho HTTP enviado pelo servidor ao responder a uma solicitação AJAX pode ser lido pelos métodos GetResponseHeader e GetAllResponseHeaders. Na maioria dos casos, você não precisa se preocupar com o que está no cabeçalho, porque eles fazem parte das transações interativas entre o navegador e o servidor. O código a seguir mostra como usar esta propriedade:
<! Doctype html> <html lang = "pt"> <head> <meta charset = "utf-8"> <meta content = "width = dispositivo de dispositivo, title-scalable = no" name = "viewport" /> <meta name = "autor =" ye a chaoluka " /> <meta" href = "../ img/ycdoit.ico" type = "image/x-icon" rel = "ícone de atalho"/> <yoy> #allheaders, #Cheader {borda: Médio Solid Black; Padding: 2px; margin: 2px;} </style> </head> <body> <div> <buttle> <buttle; <butto> Bananas </botão> </div> <div id = "Cheader"> </div> <div id = "allHeaders"> </div> <div id = "Target"> Pressione um botão </div> <cript> var Botões = document.getElementsByTagName ("Button"); for (var i = 0; i <botões.length; i ++) {botões [i] .OnClick = handleButtonPress; } var httprequest; Função HODEBTOTTONpress (e) {httPrequest = new XmlHttPrequest (); httprequest.onReadyStatechange = HandleResponse; httprequest.open ("get", e.target.innerhtml+". html"); httprequest.setRequestHeader ("Cache-Control", "No-Cache"); httprequest.send (); } function handleSponse () {if (httprequest.readyState == 2) {document.getElementById ("allHeaders"). innerhtml = httprequest.getAllResponseHeaders (); Document.getElementById ("Cheader"). Innerhtml = httprequest.getResponseHeader ("content-type"); } else if (httprequest.readyState == 4 && httprequest.status == 200) {document.getElementById ("Target"). inerhtml = httprequest.ResponseTxt; }} </script> </body> </html>As renderizações são as seguintes:
De acordo com este número, podemos ver que o software do servidor da web que o servidor de desenvolvimento está em execução é Intellij Idea 15.0.4, e a última vez que o documento de maçãs.html foi modificado foi 27 de junho (mas a captura de tela foi em 5 de julho).