</> HTML5Advent
ENFRESDEITPT

// apis · Web Platform Advent #1

A Fetch API em JavaScript: um guia prático

Como fazer requisições HTTP no navegador com a Fetch API — GET, JSON, POST, tratamento de erros e cancelamento de requisições — com exemplos executáveis.

Um editor de código na tela mostrando código-fonte HTML, CSS e JavaScript

A Fetch API é a forma moderna, baseada em promises, de fazer requisições HTTP a partir do navegador. Ela substitui o antigo XMLHttpRequest por uma interface mais limpa que funciona naturalmente com async/await e com streams. Todos os navegadores atuais a suportam.

Uma primeira requisição GET

fetch() retorna uma promise que é resolvida para um objeto Response. Para ler o JSON dela, chama-se response.json(), que por sua vez retorna uma promise:

const res = await fetch('https://api.example.com/articles');
const data = await res.json();
console.log(data);

A mesma coisa sem async/await, com cadeias de .then():

fetch('https://api.example.com/articles')
  .then((res) => res.json())
  .then((data) => console.log(data));

A armadilha: fetch não rejeita em erros HTTP

É o que surpreende quase todo mundo. Uma resposta 404 ou 500 continua sendo um fetch bem-sucedido — a promise só é rejeitada em caso de falha de rede (offline, DNS, CORS). Você mesmo precisa verificar response.ok:

const res = await fetch(url);
if (!res.ok) {
  throw new Error(`HTTP ${res.status} ${res.statusText}`);
}
const data = await res.json();
Um switch de rede com cabos, representando os dados que viajam entre cliente e servidor
Cada chamada fetch() envia uma requisição HTTP pela rede até um servidor e aguarda que a resposta faça o caminho de volta.

Enviar dados com POST

Passe um segundo argumento de opções para definir o método, os cabeçalhos e o corpo. Para JSON, serialize o payload e defina o Content-Type:

const res = await fetch('/api/articles', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ title: 'Olá', body: 'Mundo' }),
});
const created = await res.json();

Cancelar uma requisição

Use um AbortController para cancelar uma requisição — útil para tempos limite ou quando um componente é desmontado:

const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);

try {
  const res = await fetch(url, { signal: controller.signal });
  const data = await res.json();
} catch (err) {
  if (err.name === 'AbortError') console.log('Requisição expirada');
} finally {
  clearTimeout(timeout);
}

Referência rápida

TarefaComo
Ler JSONawait res.json()
Ler textoawait res.text()
Verificar o sucessores.ok / res.status
Enviar JSONbody: JSON.stringify(...) + Content-Type
CancelarAbortController + signal

Isso cobre os casos do dia a dia. A Fetch API também suporta o streaming de corpos de resposta, uploads com FormData e a clonagem de requisição/resposta — mas os padrões acima dão conta da grande maioria das chamadas reais.