Objeto XMLHttpRequest - JavaScript

O código JavaScript pode interagir com recursos na internet, como sites ou serviços web, basicamente, com servidores. Para a interação do código JavaScript com o servidor, é geralmente utilizada a tecnologia AJAX. Ajax é uma tecnologia para enviar requisições ao servidor a partir do código cliente JavaScript sem recarregar a página. O termo significa Asynchronous JavaScript And XML. Inicialmente, o AJAX foi concebido para interações assíncronas entre cliente e servidor usando dados em formato XML, embora atualmente o formato JSON tenha substituído amplamente o XML.

Um dos métodos para enviar requisições Ajax é utilizando o objeto XMLHttpRequest. Esse objeto é criado com a função construtora de mesmo nome:

const xhr = new XMLHttpRequest();

Para configurar e enviar requisições Ajax, o objeto XMLHttpRequest fornece vários métodos:

  • abort(): interrompe a requisição

  • getAllResponseHeaders(): retorna todos os cabeçalhos da resposta HTTP como uma string

  • getResponseHeader(header): retorna o valor do cabeçalho especificado

  • open(method, url[, async[, user[, password]]]): inicializa a requisição Ajax

    Essa função aceita cinco parâmetros, dos quais os dois primeiros são obrigatórios:

    • method: tipo de requisição ("GET", "POST", "PUT", "DELETE", etc.)

    • url: endereço do recurso para o qual a requisição é enviada

    • async: valor booleano que indica se a requisição será assíncrona. Se for true (padrão), a requisição é assíncrona. Os modos síncrono e assíncrono diferem em que, no modo síncrono, enquanto a requisição não for completada, o restante do código JavaScript não pode ser executado. No modo assíncrono, outras partes do código JavaScript podem ser executadas em paralelo à execução da requisição. Na maioria dos casos, é utilizado o modo assíncrono.

    • user: nome do usuário para autenticação no servidor (padrão é null)

    • password: senha do usuário para autenticação no servidor (padrão é null)

  • overrideMimeType(mime): sobrescreve o tipo MIME retornado pelo servidor

  • send(data): envia a requisição. Com o parâmetro opcional data, é possível enviar dados para o servidor. Se nenhum valor for passado, seu padrão é null.

  • setRequestHeader(header, value): define o valor do cabeçalho que será enviado na requisição.

Propriedades do XMLHttpRequest

Além dos métodos, o objeto XMLHttpRequest oferece várias propriedades para configurar a requisição ou extrair dados recebidos do servidor:

  • response: retorna a resposta do servidor. A resposta pode ser um ArrayBuffer, Blob, Document, objeto JSON, string ou null (se a requisição ainda não foi concluída ou falhou).

  • responseType: retorna o tipo de resposta. Os possíveis tipos são:

    • "": string vazia

    • arraybuffer: resposta como ArrayBuffer com dados binários

    • blob: resposta como Blob com dados binários

    • document: resposta como Document (HTML/XML)

    • json: resposta em formato JSON

    • text: resposta como texto

  • responseText: retorna a resposta do servidor como string ou null (se a requisição ainda não foi concluída ou falhou)

  • responseXML: retorna a resposta do servidor como objeto Document (HTML/XML) se a resposta estiver em formato XML/HTML

  • readyState: mantém o estado da requisição como um número:

    • 0: objeto XMLHttpRequest criado, mas o método open() ainda não foi chamado

    • 1: método open() foi chamado, mas a requisição ainda não foi enviada

    • 2: requisição enviada, cabeçalhos e status da resposta recebidos e prontos para uso

    • 3: resposta sendo recebida do servidor

    • 4: requisição concluída (mesmo que ocorra um erro, como código 404)

    Verificando essa propriedade, é possível entender em que estágio a requisição está.

  • status: contém o código de status da resposta HTTP do servidor. Com o código de status, é possível determinar o sucesso da requisição ou identificar erros. Por exemplo, código 200 indica sucesso. Código 403 indica necessidade de autenticação, e 404 informa que o recurso não foi encontrado.

  • statusText: retorna o texto do status da resposta, por exemplo, "200 OK"

  • timeout: define o tempo limite em milissegundos para a execução da requisição. Se esse tempo for excedido, a requisição é interrompida

  • withCredentials: determina se as credenciais, como cookies, devem ser incluídas na requisição

Eventos e Manipuladores de Eventos do XMLHttpRequest

Para acompanhar o estado da requisição, podemos utilizar eventos do XMLHttpRequest:

  • abort: ocorre após a interrupção da requisição. O manipulador é definido pela propriedade onabort.

  • progress: ocorre durante a execução da requisição. O manipulador é definido pela propriedade onprogress.

  • load: ocorre após a conclusão da requisição. O manipulador é definido pela propriedade onload.

  • loadend: ocorre após a conclusão bem-sucedida da requisição. O manipulador é definido pela propriedade onloadend.

  • error: ocorre quando há um erro. O manipulador é definido pela propriedade onerror.

  • loadstart: ocorre após o início da requisição. O manipulador é definido pela propriedade onloadstart.

  • timeout: ocorre se a requisição for interrompida devido ao tempo limite. O manipulador é definido pela propriedade ontimeout.

  • readystatechange: ocorre sempre que o valor da propriedade readyState muda. O manipulador é definido pela propriedade onreadystatechange.

Para definir os manipuladores de eventos, podemos usar as seguintes propriedades do XMLHttpRequest:

  • onabort: chamado quando a requisição é interrompida pelo método abort().

  • onerror: chamado quando ocorre um erro.

  • onload: chamado quando a requisição é concluída com sucesso e a resposta está disponível.

  • onloadend: chamado após a conclusão da requisição.

  • onloadstart: chamado após o início da requisição.

  • onprogress: chamado durante a execução da requisição.

  • onreadystatechange: chamado quando o estado da requisição muda.

  • ontimeout: chamado se a requisição for interrompida devido ao limite do tempo.

  • upload: usado para acompanhar o status durante o upload de dados.

Processo de Execução da Requisição Ajax

De modo geral, o processo de execução de uma requisição Ajax com o XMLHttpRequest é o seguinte:

  1. Cria-se um objeto XMLHttpRequest:

    const request = new XMLHttpRequest();
  2. Define-se um manipulador de eventos para o carregamento (por exemplo, através da propriedade onload), que será chamado após a conclusão da requisição HTTP:

    request.onload = (event) => { console.log("requisição concluída"); }
  3. Inicia-se a requisição HTTP com o método open(). Este método recebe o método HTTP a ser usado (por exemplo, GET ou POST), o URL para o qual a requisição será enviada e, se necessário, outros argumentos opcionais:

    request.open("GET", "http://localhost/hello");
  4. Se necessário, configura-se adicionalmente a requisição HTTP. Por exemplo, com o método setRequestHeader(), é possível definir cabeçalhos a serem enviados com a requisição. É importante fazer essa configuração após a chamada do método open(), mas antes da chamada do método send():

    request.setRequestHeader("Accept", "text/plain"); // define o cabeçalho para aceitar dados em texto plano
  5. Envia-se a requisição HTTP com a chamada do método send(). Se desejado, é possível passar dados para serem enviados ao servidor:

    request.send();

A seguir, vamos ver um exemplo simples de como realizar uma requisição ao servidor utilizando XMLHttpRequest:

Definindo o Recurso no Servidor

Como o Ajax envolve a interação entre cliente e servidor, precisamos de um recurso de rede ao qual faremos solicitações. Para simular um recurso de rede, usaremos um servidor web local. O servidor web pode ser qualquer um, mas neste caso, utilizaremos a opção mais simples: Node.js. Esta tecnologia é bastante simples, disponível para todos os sistemas operacionais principais e permite usar JavaScript para criar aplicações. No entanto, antes de criar a aplicação, é necessário instalar o Node.js. Não é necessário ter conhecimentos prévios de Node.js, pois todo o código utilizado será explicado detalhadamente. Contudo, ao invés do Node.js, poderia ser utilizada qualquer outra tecnologia de servidor, como PHP, ASP.NET, Python, entre outras, ou um servidor web específico como Apache ou IIS.

Primeiramente, crie uma pasta no disco rígido para os arquivos do servidor web. Por exemplo, no meu caso, a pasta é C:\app. Em seguida, dentro dessa pasta, crie um arquivo para o servidor. Vamos chamá-lo de server.js, com o seguinte código:

const http = require("http");
const fs = require("fs");

http.createServer(function(request, response) {
    if (request.url == "/hello") {
        response.end("Hello Programício");
    } else {
        fs.readFile("index.html", (error, data) => response.end(data));
    }
}).listen(3000, () => console.log("Servidor iniciado em http://localhost:3000"));

Este é o servidor mais básico, suficiente para a nossa tarefa. Vamos passar rapidamente pelo código:

Primeiro, conectamos os pacotes com a funcionalidade que vamos usar:

const http = require("http"); // para processar solicitações recebidas
const fs = require("fs");     // para ler o arquivo index.html do disco rígido

Para criar o servidor, usamos a função http.createServer(). Esta função recebe uma função de callback, que é chamada toda vez que uma solicitação chega ao servidor. Esta função tem dois parâmetros: request (contém os dados da solicitação) e response (controla o envio da resposta).

Na função de callback, usamos a propriedade request.url para determinar a qual recurso no servidor a solicitação foi direcionada. No nosso caso, se a solicitação for para o caminho "/hello" (recurso "/hello"), enviamos a resposta "Hello Programício" usando o método response.end():

if (request.url == "/hello") {
  response.end("Hello Programício");
}

Se a solicitação for para outro recurso, enviamos o arquivo index.html, que será definido a seguir:

else {
  fs.readFile("index.html", (error, data) => response.end(data));
}

Para ler arquivos, usamos a função embutida fs.readFile(). O primeiro parâmetro da função é o caminho do arquivo (neste caso, presumimos que o arquivo index.html está na mesma pasta que o arquivo do servidor server.js). O segundo parâmetro é uma função que é chamada após a leitura do arquivo, e recebe o conteúdo do arquivo através do seu segundo parâmetro data. O conteúdo lido também pode ser enviado usando a função response.end(data).

Por fim, com a função listen(), iniciamos o servidor web na porta 3000. Ou seja, o servidor será acessível através do endereço http://localhost:3000/.

Servidor Node.js para testar XMLHttpRequest em JavaScript

Executando a Requisição Ajax

Agora, na pasta do servidor, definiremos um arquivo simples chamado index.html com o seguinte conteúdo:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Programício</title>
</head>
<body>
<script>
const xhr = new XMLHttpRequest();
// Requisição GET para o recurso /hello
xhr.open("GET", "/hello");

// Manipulador de resposta do servidor
xhr.onload = () => {
    if (xhr.status == 200) { // se o código de resposta for 200
        console.log(xhr.responseText); // exibimos a resposta no console do navegador
    } else { // caso contrário, exibimos o texto do status
        console.log("Resposta do servidor: ", xhr.statusText);
    }
};
xhr.send(); // enviamos a requisição
</script>
</body>
</html>

No método xhr.open(), o tipo de requisição é "GET" e o endereço do recurso é "/hello":

xhr.open("GET", "/hello");

Para acompanhar a conclusão da requisição, definimos um manipulador para o evento load usando a propriedade xhr.onload:

xhr.onload = () => {
  if (xhr.status == 200) { // se o código de resposta for 200
      console.log(xhr.responseText); // exibimos a resposta no console do navegador
  } else { // caso contrário, exibimos o texto do status
      console.log("Resposta do servidor: ", xhr.statusText);
  }
};

Neste caso, o manipulador de eventos é uma expressão lambda. Quando a requisição é concluída, este manipulador é executado. Se a requisição foi processada com sucesso, o servidor envia o código de status 200 por padrão. Como lembramos do código do servidor, ao acessar o endereço "/hello", o servidor envia ao cliente uma string. Para obter essa string, acessamos a propriedade xhr.responseText. Se ocorrer algum erro durante a solicitação ou o código de status não for 200, usamos a propriedade xhr.statusText para exibir o texto do status da resposta.

Finalmente, enviamos a requisição:

xhr.send(); // enviamos a requisição

Dessa forma, ao carregar esta página web, uma requisição Ajax será feita ao servidor.

Agora, na linha de comando, navegue até a pasta do servidor usando o comando cd e inicie o servidor com o comando node server.js:

C:\app>node server.js
Servidor iniciado em http://localhost:3000

Após iniciar o servidor, podemos acessar o endereço http://localhost:3000 no navegador. A página será exibida, e o código JavaScript fará a solicitação ao recurso "/hello":

XMLHttpRequest em JavaScript

Ao acessar o recurso "/hello", o servidor enviará a string "Hello Programício", que poderemos receber na página web.

No exemplo acima, usamos um caminho relativo, mas também poderíamos usar um caminho absoluto especificando o protocolo, endereço do servidor e porta:

xhr.open("GET", "http://localhost:3000/hello");

Em vez de usar o evento load, também poderíamos processar o evento readystatechange do objeto XMLHttpRequest, que ocorre sempre que o valor da propriedade readyState muda:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Programício</title>
</head>
<body>
<script>
const xhr = new XMLHttpRequest();
// Requisição GET para o recurso /hello
xhr.open("GET", "/hello");

// Manipulador de resposta do servidor
xhr.onreadystatechange = () => {
    if (xhr.readyState == 4) { // se a requisição estiver concluída
        if (xhr.status == 200) { // se o código de resposta for 200
            console.log(xhr.responseText); // exibimos a resposta no console do navegador
        } else { // caso contrário, exibimos o texto do status
            console.log("Resposta do servidor: ", xhr.statusText);
        }
    }
};
xhr.send(); // enviamos a requisição
</script>
</body>
</html>

Aqui, no manipulador de eventos, primeiro verificamos o estado da requisição. Se o código de estado for 4, processamos a resposta do servidor. A lógica restante é a mesma do exemplo anterior.

Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com