Trabalhando com Fetch API e XMLHttpRequest

Blog fellyph cintra - fetch api tutorial

Nesse post vamos trabalhar com duas opções para realizar requisições assíncronas a dados no servidor XMLHttpRequest e Fetch API. Com a popularização do jQuery por muito tempo utilizamos a biblioteca para fazer requisições AJAX pela facilidade, melhorias com recursos extras e o suporte aos browsers antigos.

Mas temos um recurso antigo que nos permite realizar requisições ao servidor com Vanilla JavaScript, o XMLHttpRequest.

XMLHttpRequest

XMLHttpRequest é um objeto XHR para interação com servidores. Com ele podemos requisitar dados sem realizar o reload de todo conteúdo, para você que está programando agora isso pode parecer básico, mas não era possível no começo da web.

Suporte XMLHttpRequest API

Com a popularização do AJAX o XMLHttpRequest foi utilizado como recurso base para o conceito. O nome sugere que a API é focada em XML, mas elas podem resgatar qualquer tipo de dado.

Utilizando XMLHttpRequest

Para esse exemplo iremos fazer uma requisição a um arquivo no nosso projeto:

function onLoadRequest(event) { console.log(this.responseText); } const oRequest = new XMLHttpRequest(); oRequest.addEventListener('load', onLoadRequest); oRequest.open('GET', '/dados.json'); oRequest.send();
Code language: JavaScript (javascript)

No código acima criamos um objeto XMLHttRequest, onde adicionamos um listener para ouvir quando a requisição for lida. Assim abrimos uma requisição do tipo GET para arquivo dados.json no nosso projeto. E por fim enviamos a requisição com o método “send”

Por padrão essa requisição será assíncrona, isso significa que a execução do código continuará sendo executada e quando os dados forem recebidos a função de callback onLoadRequest será executada.

Tratando as resposta

Temos diversos tipos de atributos de respostas a requisição os principais são responseXML e responseText no exemplo anterior tratamos o responseText.

responseXML: é utilizado para tratar requisições feitas para arquivos XML, nesse tipo de requisição podemos trabalhar de quatro formas com: XPath, Parsing e serialização de XML, XMLSerializer e expressões regulares.

responseText: se você deseja ler conteúdo de texto ou de uma página web e injetar na sua página Web, esse é o caminho. Atualmente é o formato mais utilizado na web.

Monitorando o processo

No código anterior, adicionamos um listener para o evento de load, mas temos a opção de trabalhar com 5 eventos:

  • progress
  • error
  • abort
  • load
  • loadend(abort, load ou error)
// evento disparado quando a requisição for completa function onLoadRequest(event) { console.log(this.responseText); } // evento disparado quando o download do arquivo tem uma progressão function onProgressRequest (oEvent) { if (oEvent.lengthComputable) { let percentComplete = oEvent.loaded / oEvent.total * 100; console.log('Percentagem:', percentComplete + '%') } else { console.log('O total do arquivo é desconhecido'); } } const oRequest = new XMLHttpRequest(); oRequest.addEventListener('load', onLoadRequest); oRequest.addEventListener('progress', onProgressRequest) oRequest.open('GET', '/dados.json'); oRequest.send();
Code language: JavaScript (javascript)

Caso algo de errado aconteça podemos realizar uma verificação para realizar um tratamento. Assim vamos adicionar uma condicional no nosso código:

function onLoadRequest(event) { if(this.status === 200) { console.log(this.responseText) } else { console.log('Somthing wrong happen:',this.status); } }
Code language: JavaScript (javascript)

No código acima verificamos se o status da requisição é 200(sucesso) caso contrário exibimos o status, dai temos uma várias possibilidades: 404, 401, 500…

Fetch API

Fetch API é uma melhoria sobre a XMLHttpRequest. Ela traz a possibilidade de trabalhar com interface para administrar as requisições de recursos na rede, anteriormente tínhamos XMLHttpRequest para acompanhar requisições na rede, mas era uma API bem limitada comparada com as necessidades das aplicações modernas que temos hoje em dia. Por outro lado, a sua desvantagem que ela está presente apenas nos browsers modernos.

Suporte do browsers para Fetch API

Principal diferença que agora com Fetch Api podemos ter objetos específicos para requisições(Request) e repostas(Response). Isso permite que elas sejam utilizadas em diferentes situações como, por exemplo, Service Workers e Cache API.

Ela também fornece uma definição para conceitos relacionados, como CORS e semântica de cabeçalhos HTTP.

Utilizando fetch API

Para realizar uma requisição com fetch API, chamamos o método fetch() presente no Window ou em um Worker global. O método tem como parâmetro obrigatório o caminho do arquivo ao qual desejamos requisitar. Agora vamos para um exemplo simples com fetch API:

fetch('/dados.json') .then((response) => console.log(response));
Code language: JavaScript (javascript)

Primeira diferença, é a quantidade de linhas que escrevemos, também a opção de se trabalhar com Promises. No caso acima realizamos uma requisição para o mesmo endereço caso sucesso exibimos no nosso console o tipo de resposta que será seguinte, um objeto do tipo Response com as seguintes informações:

body: (...) bodyUsed: false headers: Headers __proto__: Headers ok: true redirected: false status: 200 statusText: "OK" type: "basic" url: "http://127.0.0.1:5500/dados.json"
Code language: HTTP (http)

Com podemos ver temos o corpo de nossa resposta que terá:

  • O nosso conteúdo
  • Status da requisição e do conteúdo
  • Informações sobre redirecionamento
  • Tipo da requisição
  • Cabeçalho da requisição

Se compararmos como XMLHttpRequest as informações serão as seguinte:

onabort: null onerror: null onload: null onloadend: null onloadstart: null onprogress: null onreadystatechange: null ontimeout: null readyState: 4 response: "{↵ "name":"fellyph",↵ "sobrenome": "cintra",↵ "blog": "https://blog.fellyph.com.br"↵}" responseText: "{↵ "name":"fellyph",↵ "sobrenome": "cintra",↵ "blog": "https://blog.fellyph.com.br"↵}" responseType: "" responseURL: "http://127.0.0.1:5500/dados.json" responseXML: null status: 200 statusText: "OK" timeout: 0 upload: XMLHttpRequestUpload {onloadstart: null, onprogress: null, onabort: null, onerror: null, onload: null, …} withCredentials: false
Code language: JavaScript (javascript)

Como podemos ver temos a informações de requisições, respostas e eventos tudo num lugar só, isso dificulta o tratamento da informação e realiza um consumo de dados desnecessário para o usuário.

Na requisição anterior caso queiramos tratar os dados da resposta fazemos da seguinte forma:

fetch('/dados.json') .then(response => response.json()) .then(data => console.log(data));
Code language: JavaScript (javascript)

Para o tratamento de erros realizamos da seguinte forma, adicionamos um catch na chamada de nosso catch:

fetch('/dados.json') .then(response => response.json()) .then(data => console.log(data)); .catch(error => { console.log('Algo de errado aconteceu:', error ) });
Code language: JavaScript (javascript)

Tipos de requisição

A fetch api pode realizar requisições para diferentes tipos de dados, como texto, images, como processar arquivos de text linha a linha. Além disso podemos enviar informações e realizar upload de arquivos.

Um exemplo de um envio de um arquivo json:

const data = { name: 'fellyph', sobrenome: 'cintra', blog: 'https://blog.fellyph.com.br' }; fetch('/usuario', { method: 'POST', // ou 'PUT' headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }) .then(response => response.json()) .then(data => { console.log('Success:', data); }) .catch((error) => { console.error('Error:', error); });
Code language: JavaScript (javascript)

Suporte

Fetch API é suportada por 95% dos browsers, os browsers que não possuem suporte:

  • Internet Explorer 11
  • Edge 13 e inferior

Podemos verificar o suporte da seguinte forma:

if (window.fetch) { // realizamos o request com fetch } else { // utilizamos um fallback }
Code language: JavaScript (javascript)

XMLHttpRequest vs. Fetch API

Eles surgiram em tempos diferentes, por muito tempo XMLHttpRequest deu conta do recado mas com a evolução das aplicações web começamos a ter a necessidade de multiplas requisições, foi que então começamos a ter problemas com correntes de callbacks requisições a diferentes serviços.

Para solucionar esse problema tivemos a introdução de promises e junto a ela tivemos a inclusão de novas APIs que começaram a utilizar esse recurso como Fetch API, Service Worker entre outras Web APIs.

Podemos dizer que Fetch API é a evolução da XMLHttpRequest. Apesar da estrutura ter mudado drasticamente elas possuem o mesmo objetivo solucionar o problema com requisições assíncronas. Além de ser extremamente poderosa.

Para mais tutoriais sobre desenvolvimento web acesse a página da categoria tutoriais.

Por Fellyph Cintra

Fellyph Cintra é um Google Developer Expert focado em tecnologias web, com participação ativa na comunidade WordPress. Com mais de 14 anos de experiência no mercado, Fellyph já palestrou em mais de 30 eventos ao redor do Brasil e Europa, sempre abordando as boas práticas de desenvolvimento na web.

1 comentário

  1. Amigo, me chamo Jacivam, sou de manaus, estou tentando trabalhar com essa api Fecht com Java|script.
    Mais estou tendo muita dúvidas de como colocar o resultado em uma variavel fora dessa função, e trabalhar com os resultados. Meu codigo abaixo.

    … Buscar dados …

    var form = document.getElementsByTagName(‘form’)[0];

    // Quando ocorrer um evento submit (envio )
    form.addEventListener(“submit”, getData);

    var ValorRespostaDaUrl = {};

    // Enviando dados para o servidor
    function getData(event){

    // Nao permite a execucao do padao do formulario
    event.preventDefault()

    //data no formato de JSON
    let data = {db:{DO:’SELECT’,TABLE:’SYSUsuario’},
    key:’null’,
    field:{UsuarioId:”,Nome:”, Senha:”,CCustoId:”,SetorId:”},
    orderby:{UsuarioId:’null’} } ;
    fetch(“./appServerRetornaY.php”, {
    headers: new Headers({“Content-Type”: “application/json”,}),
    method: “POST”,
    body: JSON.stringify(data),
    })
    .then(response => {return response.json(); } )
    .then(json => {Sucesso(json); } )
    .catch(err => console.log(err) );

    }

    function Sucesso(data) {
    ValorRespostaDaUrl = data ;
    };

    for (var i=0; i<ValorRespostaDaUrl.length; i++){
    trabalhando com os dados……vindo da url,
    essa é minha dificuldade não consigo colocar os dados nesta variavel.
    Por que tudo que esta neste bloco é processado antes do resultado da URL.
    }
    }

Deixe um comentário

O seu endereço de e-mail não será publicado.