Categorias do Site

Guia Completo do Fetch API em JavaScript

Descubra como usar o Fetch API em JavaScript para requisitar dados de servidores remotos ou locais de forma eficiente.

Um fundo texturizado em degrade de azul para vermelho com dois círculos sobrepostos; o da esquerda preto com a palavra


Como o nome sugere, o Fetch API é uma maneira fácil de buscar recursos de um servidor remoto ou local por meio de uma interface JavaScript.

Guia Completo do Fetch API em Javascript

O método fetch() permite que o navegador faça requisições HTTP diretamente aos servidores web. Ele retorna uma promessa cuja resposta é cumprida usando o objeto Response.

O método fetch() requer um argumento obrigatório, que é o caminho para o servidor remoto ou fonte de onde queremos buscar dados. Após receber a resposta, o desenvolvedor decide como lidar com o conteúdo e exibi-lo em um template HTML, por exemplo.

Veja um exemplo básico de fetch() que busca dados de um servidor remoto:

fetch(url)
  .then(
    // handle the response
  )
  .catch(
    // handle the errors
  )

O exemplo acima usa promessas simples para implementar o método fetch(). Especificamos uma URL e a armazenamos em uma variável const. No decorrer deste artigo, ajustaremos este trecho de código para mostrar como aproveitar ao máximo o Fetch API ao fazer chamadas.

Trabalhando com o método fetch()

Para seguir este guia, você precisará de um entendimento básico de conceitos de JavaScript, como promessas, async/await e funções de callback.

Para este tutorial, queremos simular um ambiente de trabalho com uma API. Usaremos um JSON placeholder, uma API falsa e gratuita para testes, que servirá como meio de alcançar nosso servidor.

GET requests

Uma requisição GET é usada para recuperar dados de um servidor. Por padrão, todas as requisições HTTP são GET a menos que especificado o contrário.

Por exemplo, se estivermos criando um aplicativo de lista de tarefas, precisamos buscar e exibir as tarefas no front end. Usando JavaScript, podemos direcionar uma lista não ordenada (ul) em nosso HTML e preenchê-la dinamicamente com os dados buscados. Veja como configurar a estrutura HTML:

Quando inserimos um item na lista de tarefas, ele é armazenado em nosso servidor. Para recuperar esses itens, usamos a requisição GET.

A primeira coisa a fazer em nosso JavaScript é obter o elemento ul do DOM via seu ID para que possamos anexar itens de lista a ele mais tarde:

const ul = document.getElementById("list")

Em seguida, armazenamos a URL da API que nos conecta ao servidor remoto em uma variável chamada URL:

const url = "https://jsonplaceholder.typicode.com/todos"

Obtivemos as variáveis necessárias. Agora podemos trabalhar com fetch(). Lembre-se de que o método fetch() leva em consideração apenas um parâmetro: a URL. Neste caso, passaremos nossa variável url:

fetch(url)

Isso por si só não nos dará os dados necessários, pois a resposta não está no formato JSON. Precisamos analisá-la para que possamos trabalhar com os dados e exibi-los em nosso HTML. Para fazer isso, usamos o método .json():

fetch(url)
  .then(response => response.json())

Após executar o fetch(), ele retorna uma promessa que é resolvida para um objeto Response. O método .then() acima é usado para processar esse objeto Response. O método .json() é chamado no objeto, retornando outra promessa que se resolve nos dados JSON de que precisamos:

fetch(url)
  .then(response => response.json())
  .then(data => {

  })

O segundo .then() acima é usado para lidar com os dados JSON retornados pelo .then() anterior. O parâmetro data é o dado JSON analisado.

Agora que temos os dados, como os exibiremos no template HTML para torná-los visíveis na página?

Temos um elemento ul e queremos exibir os dados como uma lista de itens de tarefas. Para cada item de tarefa que buscamos, criaremos um elemento li, definiremos o texto para o item buscado e, em seguida, anexaremos o li ao elemento ul.

Veja como fazer isso:

fetch(url)
  .then(response => response.json())
  .then(data => {
    data.forEach(todo => {
    const li = document.createElement("li")
    li.innerText = todo.title
    ul.appendChild(li)
    })
  })

Nossa lógica completa em JavaScript deve ficar assim:

const ul = document.getElementById("list")
const url = "https://jsonplaceholder.typicode.com/todos"

fetch(url)
  .then(response => response.json())
  .then(data => {
    data.forEach(todo => {
    const li = document.createElement("li")
    li.innerText = todo.title
    ul.appendChild(li)
    })
  })

Com isso, devemos ver uma lista de itens de tarefas exibidos na página da web. Por padrão, o JSONPlaceholder retorna um máximo de 200 itens de tarefas, mas podemos sempre ajustar nossa lógica para diminuir esse número. Podemos obter mais do que apenas o título dos itens de tarefas. Um exemplo de mais dados que poderíamos encontrar poderia ser o status da tarefa.

POST requests

Agora que vimos como obter dados do servidor, veremos como adicionar dados ao servidor. Imagine preencher um formulário ou inserir dados em um site. Esses dados precisam chegar ao banco de dados de alguma forma, e geralmente conseguimos isso usando requisições POST.

Em nosso código HTML, teremos um pequeno formulário com um campo de entrada e um botão de envio:

Em seguida, em JavaScript, queremos capturar dois elementos e especificar a URL, através da qual fazemos as requisições:

const form = document.getElementById("todo-form");
const input = document.getElementById("todo-input");

const url = "https://jsonplaceholder.typicode.com/todos"

Criamos um ouvinte de eventos para que a requisição seja feita cada vez que enviamos o formulário:

form.addEventListener("submit", (event) => {
  event.preventDefault()

})

Os dados geralmente são enviados para o backend como objetos com pares de chave-valor específicos representando o formato em que queremos armazenar nossos dados. Em nosso caso, queremos armazenar o título e o status de um item de tarefa.

Por exemplo:

const newToDo = {
  title: input.value,
  completed: false,
}

Agora, podemos começar a configurar nossa requisição POST. Ao contrário da requisição GET, que requer apenas um parâmetro, a requisição POST precisa de dois. O primeiro é a URL, e o segundo é um objeto que inclui as chaves method, body e headers:

fetch(url, {
    method: "POST",
    body: JSON.stringify(newTodo),
    headers: {
      "Content-Type": "application/json",
    },
})

A chave method define o tipo de requisição sendo feita. Neste caso, está definido como POST, indicando que estamos enviando dados para o servidor. O body contém os dados, formatados como uma string JSON usando JSON.stringify(newTodo). Vamos abordar os headers na próxima seção.

Estes são os fundamentos de uma simples requisição POST. Nossa lógica final em JavaScript ficará assim:

const form = document.getElementById("todo-form");
const input = document.getElementById("todo-input");

const url = "https://jsonplaceholder.typicode.com/todos";

form.addEventListener("submit", (event) => {
  event.preventDefault();
  const newTodo = {
    title: input.value,
    completed: false,
  };

  fetch(url, {
    method: "POST",
    body: JSON.stringify(newTodo),
    headers: {
      "Content-Type": "application/json",
    },
  });
});

Além de GET e POST, existem várias outras operações que você pode usar ao trabalhar com dados. Você pode visitar a documentação do MDN para aprender mais sobre essas requisições e como usá-las.

Tratamento de erros

Até agora, nossos exemplos de GET e POST assumem que tudo corre bem, mas e se não acontecer? O que acontece se o recurso não existir ou um erro de rede ocorrer ao enviar dados?

Para lidar com esses casos, podemos adicionar um método .catch para capturar erros de rede e verificar o status da resposta para lidar com erros HTTP. Vamos ver como tornar nossas requisições fetch mais resilientes.

Vamos reformular o código acima para considerar possíveis erros:

form.addEventListener("submit", (event) => {
  event.preventDefault();
  const newTodo = {
    title: input.value,
    completed: false,
  };
  fetch(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(newTodo),
  })
    .then((response) => {
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }
      console.log("Todo added")
    })
    .catch((error) => {
      console.error("Error:", error);
    });
});

Usamos .then para verificar se a resposta está OK—se não, lançamos um erro com o código de status. Então, .catch trata qualquer erro de fetch e os registra no console.

O tratamento adequado de erros garante que os problemas sejam detectados e comunicados de forma eficaz. Os códigos de status HTTP desempenham um papel importante aqui, pois cada um tem um significado específico e exige uma resposta diferente. Alguns dos códigos de status mais comuns incluem:

  • 200 OK
  • 404 Not Found
  • 500 Internal Server Error

Transmitindo dados de requisições Fetch

Ao trabalhar com grandes quantidades de dados, nem sempre podemos esperar para buscar completamente todos os dados do servidor antes de processá-los. O streaming é uma técnica que nos permite processar dados em blocos. Os dados são processados dessa forma até serem todos recuperados do servidor. Isso é uma maneira de melhorar a capacidade de resposta e o desempenho da aplicação.

Vamos transformar nosso exemplo anterior de requisição GET em um que implemente streaming.

Iniciamos a requisição para a API e verificamos se a resposta está OK:

fetch(url)
  .then(response => {
    if(!response.ok){
      throw new Error(`HTTP error! status: ${response.status}`)
    }

  })

Precisamos de um leitor para ler o corpo da resposta em blocos e decodificar os blocos em texto. Essa decodificação é feita com a ajuda do TextDecoder():

const reader = response.body.getReader()
const decoder = new TextDecoder()
let result = ""

Após ler o primeiro bloco, processamos. Se o stream estiver completo, ele registra uma mensagem no console e retorna. Se não, decodifica o bloco de dados, anexa ao resultado string, analisa como JSON e anexa cada item de tarefa à lista.

Em seguida, lê o próximo bloco de dados e processa recursivamente:

return reader.read().then(function processText({ done, value }) {
        if (done) {
          console.log("Stream complete")
          return
        }

        // decode and parse JSON
        result += decoder.decode(value, { stream: true });
        const todos = JSON.parse(result)

        // add each to-do to the list
        todos.forEach((todo) => {
          const li = document.createElement("li")
          li.innerText = todo.title
          list.appendChild(li)
        })
        return reader.read().then(processText)
})

No final, podemos adicionar um .catch para considerar quaisquer erros:

.catch((error) => {
  console.error("Error", error)
})

Nosso arquivo JavaScript final para streaming ficaria assim:

const list = document.getElementById("to-do");
const url = "https://jsonplaceholder.typicode.com/todos";


  fetch(url)
    .then((response) => {
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const reader = response.body.getReader()
      const decoder = new TextDecoder()
      let result = ""
      return reader.read().then(function processText({ done, value }) {
        if (done) {
          console.log("Stream complete")
          return
        }
        result += decoder.decode(value, { stream: true });
        const todos = JSON.parse(result)
        todos.forEach((todo) => {
          const li = document.createElement("li");
          li.innerText = todo.title
          list.appendChild(li)
        })
        return reader.read().then(processText);
      })
    })
    .catch((error) => {
      console.error("Error:", error);
    })

Como usar headers no fetch

Além de servir e receber dados do cliente, o servidor precisa entender cada requisição que recebe. Isso é possível com a ajuda dos headers, que agem como metadados e acompanham as requisições. Esses pares de chave-valor dizem ao servidor que tipo de requisição o cliente está fazendo e como responder a ela.

Para entender os headers, devemos discutir as duas categorias que existem: headers de requisição fetch e headers de resposta fetch.

Headers de requisição fetch

Como o nome sugere, os headers de requisição dizem ao servidor que tipo de requisição você está fazendo e podem incluir condições que o servidor precisa cumprir antes de responder.

Em nosso exemplo de POST, usamos o header Content-Type para especificar que estávamos enviando dados JSON. Outro header importante é Authorization, que carrega detalhes de autenticação, como tokens ou chaves de API para acesso seguro à API. O header Accept diz ao servidor qual formato de dados preferimos na resposta.

Alguns headers, conhecidos como nomes de headers proibidos, são automaticamente definidos pelo navegador e não podem ser modificados programaticamente. Esses são chamados de nomes de headers proibidos.

Resposta fetch

Quando o servidor processa uma requisição, ele responde com headers que fornecem detalhes importantes sobre a resposta.

Headers de resposta chave incluem Status Code, que indica se a requisição foi bem-sucedida (200 OK) ou encontrou um problema (500 Server Error). Content-Length especifica o tamanho dos dados retornados, enquanto Content-Type revela o formato, como JSON ou HTML.

Alguns headers funcionam em ambas as requisições e respostas, como:

  • Cache-Control: Gerencia o comportamento de cache do navegador.
  • Accept-Encoding: Diz ao servidor quais formatos de compressão o cliente suporta.

Os headers ajudam a agilizar a comunicação entre o cliente e o servidor, melhorando o tratamento das respostas. Para um mergulho mais profundo, confira esta lista completa de headers.

Fetch API vs. Axios vs. XMLHttpRequest

A Fetch API é o padrão moderno para fazer requisições em JavaScript, mas é útil compará-la com métodos mais antigos como Axios e XMLHttpRequest para entender suas vantagens. Aqui está uma comparação abrangente:

Recurso Fetch API Axios XMLHttpRequest
Manipulação de JSON É necessário fazer parsing manual Parsing automático de JSON Parsing manual necessário
Manipulação de erros Requer verificações manuais (por exemplo, adicionando métodos .catch() e !response.ok) Manipulação de erros embutida Complexo e inconsistente
Suporte a navegadores Apenas navegadores modernos Navegadores modernos Excelente suporte a navegadores, incluindo os antigos
Cancelamento de requisições Usando AbortController, isso é suportado Suportado Não suporta cancelamento de requisições
Sintaxe Faz uso de promessas, com uma sintaxe curta e limpa Também faz uso de promessas Usa principalmente callbacks e é muito verboso

Conclusão

Neste guia, cobrimos os fundamentos do Fetch API, desde fazer requisições GET e POST simples até lidar com erros, trabalhar com headers e gerenciar respostas de streaming. Embora haja muito mais a explorar, essa base o capacita a usar o fetch em JavaScript com confiança. Dominar esses conceitos ajudará você a construir aplicações web mais eficientes e confiáveis.

  • Problemas com React Server Components

    Descubra os desafios e surpresas ao usar React Server Components em projetos reais.

    Descubra os desafios e surpresas ao usar React Server Components em projetos reais.

    Ler notícia completa
    Ícone de átomo neon azul-ciano flutuando sobre fundo roxo com linhas e pontos brilhantes, sugerindo um ambiente digital ou espaço cósmico.
  • Chave para IA Geral: Anotação Ética é Essencial

    Anotação ética é crucial para a IA Geral, garantindo respeito aos anotadores e criando consciências justas.

    Anotação ética é crucial para a IA Geral, garantindo respeito aos anotadores e criando consciências justas.

    Ler notícia completa
    Ilustração estilizada de quatro pessoas trabalhando em computadores, com um fundo de rede neural e um documento flutuante à direita, em tons azuis e laranja.
  • Como reduzir a troca de tarefas no design UX

    Descubra como otimizar a experiência do usuário reduzindo a troca de tarefas em plataformas digitais complexas.

    Descubra como otimizar a experiência do usuário reduzindo a troca de tarefas em plataformas digitais complexas.

    Ler notícia completa
    Ícone de personagem estilizado, parecido com um boneco, segurando um laptop e um celular, com um balão de fala acima, sobre um fundo abstrato cintilante e colorido.
  • Confissões de um Generalista em Web Design

    Existe um tipo especial de designer web por aí. Eles são os generalistas, aqueles que fazem a internet moderna funcionar, muitas vezes sem reconhecimento. Bem-vindo ao Multiverso de Você Você sabe quem é. Você projeta o site, constrói, escreve o texto quando ninguém mais aparece. Você lida com o CMS e descobre por que o […]

    Descubra o papel crucial do generalista em web design e sua habilidade única de gerenciar caos e criar soluções.

    Ler notícia completa
    Homem surpreso com cabelo despenteado e óculos redondos segura uma caneca e cabos, cercado por coloridos papéis adesivos em fundo laranja e verde.
  • Roteamento de IA: Apps mais inteligentes com SDK

    Se você está desenvolvendo aplicações de IA, provavelmente está lidando com mais de um modelo de linguagem em sua aplicação: GPT-4 para tarefas gerais, Claude para codificação ou até mesmo o mais recente Nano Banana para geração de imagens. Durante o desenvolvimento, você pode querer experimentar modelos de código aberto localmente, caso seu hardware suporte. […]

    Aprenda a usar o roteamento de modelos sensível ao ambiente para criar apps de IA mais eficientes com o AI SDK.

    Ler notícia completa
    Círculo preto central com um triângulo branco sobre fundo que se assemelha a uma nuvem rosa gradientemente colorida.
  • Práticas de segurança para projetos com IA

    Assistentes de código com IA são comuns em IDEs devido à produtividade que trazem, mas uma pesquisa de Stanford revelou que desenvolvedores com assistência de IA tendem a criar códigos menos seguros. Para proteger um fluxo de trabalho assistido por IA, é necessário adotar uma disciplina ativa e multifacetada. Este artigo apresenta um guia prático […]

    Descubra práticas essenciais para proteger projetos gerados por IA e evitar vulnerabilidades comuns.

    Ler notícia completa
    Ilustração de um labirinto estilizado em tons de roxo e azul, com um grande símbolo de cadeado roxo no centro, representando segurança ou privacidade.
  • Interfaces de Voz e Imersão: Futuro da Experiência UX

    “As tecnologias mais profundas são aquelas que desaparecem. Elas se integram ao tecido da vida cotidiana até se tornarem indistinguíveis dela.” — Mark Weiser Seus usuários já estão interagindo com dispositivos por voz. Nos EUA, 62% dos adultos usam assistentes de voz, enquanto 42% das famílias no Reino Unido possuem dispositivos com essa funcionalidade. Eles […]

    Prepare seu produto para o futuro das interfaces de voz e imersão, que estão transformando a interação digital.

    Ler notícia completa
    Design gráfico com fundo azul escuro apresentando as palavras
  • Por que PMs e designers precisam de ambiente AI

    Resumo Executivo Agentes de IA estão avançando de protótipos para produção, mas muitos falham sem a base correta: um ambiente de execução de agentes de IA. Pesquisas do MIT revelam que 95% dos testes de IA generativa não geram impacto mensurável. A Forbes destaca que dados fragmentados e sinais conflitantes condenam a maioria dos pilotos, […]

    Ambiente de execução AI é essencial para sucesso de projetos, evitando falhas de integração e otimizando processos.

    Ler notícia completa
    Pintura abstrata de um horizonte de cidade com edifícios coloridos sob um céu geométrico dividido em seções coloridas com linhas conectando pontos.
  • Melhores Modelos de Relatórios para InDesign e Photoshop

    Relatórios empresariais podem abranger uma ampla gama de usos, desde grandes relatórios anuais até folhas de produtos de uma página. Criar um design detalhado do zero pode ser demorado. Como equilibrar eficiência e estética? Os modelos de relatórios empresariais e corporativos desta coleção são a solução ideal. Eles são pré-desenhados, personalizáveis e compatíveis com aplicativos […]

    Descubra modelos de relatórios empresariais para InDesign e Photoshop em 2025. Otimize seus designs e economize tempo.

    Ler notícia completa
    Diversas páginas de um relatório corporativo abertas, mostrando gráficos, fotos e textos sobre negócios e finanças, em design moderno e limpo.