A Fetch API é uma interface moderna em JavaScript que simplifica as requisições HTTP com sua sintaxe baseada em promises, tornando seu código mais limpo e fácil de usar. Com a Fetch API, você pode solicitar dados do servidor sem precisar recarregar a página inteira, tornando sua aplicação mais rápida e interativa. Você pode facilmente enviar requisições GET, POST, PUT ou DELETE para interagir com diversas APIs. A Fetch API também torna simples o manuseio de diferentes tipos de dados e métodos HTTP. Personalizar cabeçalhos de requisição e gerenciar diferentes tipos de conteúdo se torna simples, permitindo que você trabalhe de forma integrada com diversos serviços.
Neste artigo, você aprenderá como usar a Fetch API, seus benefícios para aplicações web e o uso de proxies para garantir um manuseio de dados seguro e eficiente. Confira esta lista dos melhores provedores de proxy para entender por que a Bright Data é a melhor escolha.
Compreensão da Fetch API
A Fetch API é usada para fazer requisições HTTP assíncronas, enviando uma solicitação ao servidor e retornando uma promise que é resolvida com os dados da resposta assim que estiverem disponíveis. No desenvolvimento em JavaScript, o uso da Fetch API permite a interação dinâmica com servidores por meio de requisições HTTP (ou seja, GET, POST, PUT), permitindo que as aplicações se comuniquem com o servidor sem a necessidade de recarregar a página. A seguir estão alguns dos benefícios da Fetch API:
- Sintaxe simplificada com promises: A Fetch API elimina a complexidade do XMLHttpRequest ao usar promises, permitindo que você escreva um código mais limpo e legível.
- Vários formatos de dados são compatíveis: Você pode usar os formatos JSON, texto e blob, o que facilita a análise e o trabalho com diferentes tipos de resposta.
- Objetos de fluxo e resposta são fornecidos: Você pode examinar e modificar as respostas com fluxos legíveis, ajustando sua abordagem de recuperação de dados conforme a necessidade da sua aplicação.
- Melhor tratamento de erros: Por padrão, o Fetch não gera um erro para códigos de status HTTP de erro, mas permite que você faça verificações de resposta mais explícitas.
- Callbacks menos complicados: Você não precisa escrever muitos callbacks; em vez disso, pode usar
.then()
,.catch()
ouasync/await
para saber quando as requisições são concluídas.
Agora que você explorou os benefícios de usar a Fetch API, vamos analisar suas principais características e capacidades.
Operações Assíncronas
A Fetch API é assíncrona, e a promise é resolvida assim que a resposta do servidor estiver disponível. Dessa forma, você não bloqueia a interface para os seus usuários, proporcionando uma experiência mais fluida. Vamos explorar alguns exemplos.
Requisição GET
Aqui está um exemplo de como usar a Fetch API para enviar uma requisição GET:
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log('Data fetched:', data);
})
.catch((error) => {
console.error('Fetch error:', error);
});
Neste trecho, a Fetch API obtém posts de jsonplaceholder.typicode.com
. Verifica se a resposta está “Ok” usando response.ok
e gera um erro caso contrário. Em seguida, ele analisa a resposta para JSON com response.json()
. Todos os erros, seja por problemas de rede, respostas mal formadas ou falhas de análise, são tratados no bloco .catch()
.
Requisição POST
Veja como usar a Fetch API para enviar uma requisição POST:
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
body: JSON.stringify({
title: 'New Post',
body: 'Hello World! This is a test.',
userId: 1,
}),
})
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log('New Post created:', data);
})
.catch((error) => {
console.error('Fetch error:', error);
});
Aqui, a Fetch API envia uma requisição para criar um novo recurso com o método POST. A requisição POST é semelhante à requisição GET, mas a requisição inclui cabeçalhos para informar ao servidor que a API está enviando dados em formato JSON. Os dados JSON reais ficam na chave de body.
Integração com APIs
Você pode usar a Fetch API para fazer requisições a APIs públicas ou privadas, como recuperar dados para gráficos, dashboards ou outras funcionalidades baseadas em dados. Ela permite que aplicações web se comuniquem com serviços externos usando seu fluxo baseado em promises para lidar com requisições e respostas.
Aqui está um exemplo básico de como você poderia obter dados meteorológicos da OpenWeatherMap API:
const city = "London,uk";
const apiKey = "YOUR_API_KEY";
const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&APPID=${apiKey}`;
fetch(url)
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then((weatherData) => {
console.log("Weather data for London:", weatherData);
})
.catch((error) => {
console.error("Error fetching weather data:", error);
});
Substitua
YOUR_API_KEY
pela sua chave de API real.
Este código recupera dados de clima para Londres usando a API da OpenWeather. O objeto weatherData
inclui detalhes como temperatura, umidade e condições, que você pode integrar na sua interface de usuário (UI).
Depois de executar este código no seu terminal ou shell (usando o comando node filename.js
), você deverá ver uma saída como a seguinte:
Weather data for London: {
coord: { lon: -0.1257, lat: 51.5085 },
weather: [
{
id: 804,
main: 'Clouds',
description: 'overcast clouds',
icon: '04d'
}
],
base: 'stations',
main: {
temp: 273.42,
feels_like: 273.42,
temp_min: 272.59,
temp_max: 274.87,
pressure: 1021,
humidity: 87,
sea_level: 1021,
grnd_level: 1016
},
visibility: 10000,
wind: { speed: 0.51, deg: 0 },
clouds: { all: 99 },
dt: 1736525048,
sys: {
type: 2,
id: 268730,
country: 'GB',
sunrise: 1736496173,
sunset: 1736525567
},
timezone: 0,
id: 2643743,
name: 'London',
cod: 200
}
Aplicativos frequentemente precisam interagir com APIs externas para buscar dados de fontes externas. Portanto, usar uma abordagem limpa e consistente para integrar qualquer serviço externo é uma parte fundamental na construção de uma aplicação web escalável.
Tratamento de Erros
Comparado aos métodos antigos de AJAX, como XMLHttpRequest, que exigiam configurar múltiplos manipuladores de eventos para gerenciar erros de rede, o Fetch simplifica o tratamento de erros usando promises e um único bloco .catch()
. O Fetch rejeita uma promise somente se ocorrer um erro de rede (por exemplo, sem conexão com a internet). Ele não gera um erro para códigos de erro HTTP como 404
ou 500
. Para verificar se um desses erros ocorreu, você precisa verificar manualmente response.ok
. Se response.ok
for falso
, isso significa que o servidor respondeu com um status fora da faixa de 200 a 299. O exemplo a seguir mostra como o Fetch lida com erros quando uma requisição falha devido a um endpoint inválido:
fetch('https://jsonplaceholder.typicode.com/invalid-endpoint')
.then((response) => {
if (!response.ok) {
throw new Error(`Failed to fetch. Status: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log('This will not run if response is not ok');
})
.catch((error) => {
console.error('Network or response error:', error.message);
});
Ao executar este código, você receberá uma mensagem de saída: Network or response error: Failed to fetch (Erro de rede ou resposta: Falha ao buscar). Status: 404
. O código verifica !response.ok
e gera um erro porque o endpoint não existe.
Uso de Proxies com a Fetch API
Proxies podem aprimorar as capacidades da Fetch API, fornecendo segurança adicional, escalabilidade e recursos de geolocalização. Proxies funcionam como intermediários entre o seu cliente e a internet, fornecendo endereços IP exclusivos, camadas adicionais de segurança e uma abordagem mais flexível para buscar recursos. Usar proxies com o Fetch pode ajudar a evitar que seu endereço IP seja bloqueado, proporcionando anonimato durante a extração de dados ou atividades de raspagem da web. Alguns outros benefícios do uso de Proxies incluem o seguinte:
- Segurança aprimorada: Os proxies ocultam seu endereço IP, reduzindo o risco de sua IP ficar vulnerável a ataques maliciosos.
- Escalabilidade: Proxies podem distribuir requisições por vários IPs, prevenindo limites de taxa ou bloqueios.
- Flexibilidade de geolocalização: Proxies são usados para enviar requisições HTTP de diferentes locais, o que é útil para acessar conteúdo disponível apenas em regiões específicas.
Tipos de Proxies
Existem diferentes tipos de proxies, cada um atendendo a um caso de uso específico. Esses diferentes tipos de proxies são os seguintes:
- Proxies residenciais: Esses proxies utilizam IPs de locais residenciais reais e são altamente confiáveis por sites, tornando-os mais caros, mas também mais eficazes caso os sites alvo bloqueiem tráfego de IPs de datacenters.
- Proxies rotativos: Esses proxies rotacionam automaticamente os IPs a cada requisição ou sessão. Eles são ideais para extração de dados em grande escala quando você deseja reduzir o risco de atingir limites de servidor ou listas negras.
- Proxies de datacenter: Esses proxies vêm de datacenters; são econômicos e oferecem alta velocidade, mas você pode ser bloqueado se usá-los com frequência.
Proxies da Bright Data com Fetch API
A Bright Data fornece serviços avançados de proxy que se integram a aplicações baseadas em Fetch. Esses proxies permitem que você escolha entre opções residenciais ou de datacenter, escalone suas capacidades de recuperação de dados para projetos em nível empresarial e se beneficie da rotação automática de IPs para uma coleta de dados eficiente e confiável.
Veja como integrar os proxies da Bright Data com Fetch API:
import fetch from "node-fetch";
import { HttpsProxyAgent } from "https-proxy-agent";
const proxyHost = "BRIGHT_DATA_PROXY_HOST:PORT";
const proxyUsername = "BRIGHT_DATA_USERNAME";
const proxyPassword = "BRIGHT_DATA_PASSWORD";
const proxyUrl = `http://${proxyUsername}:${proxyPassword}@${proxyHost}`;
const targetUrl = "https://jsonplaceholder.typicode.com/posts";
// Create a proxy agent
const agent = new HttpsProxyAgent(proxyUrl);
fetch(targetUrl, { agent })
.then((response) => {
if (!response.ok) {
throw new Error(`Error fetching data. Status: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log("Data fetched via proxy:", data);
})
.catch((error) => {
console.error("Proxy fetch error:", error);
});
Este código envia uma requisição através de um proxy específico usando fetch
com um HttpsProxyAgent.
. Em seguida, ele define os detalhes do proxy e cria um agente de proxy. O fetch
também obtém os dados da URL de destino usando o proxy.
Para configurar um proxy, você deve usar a
Fetch API
donode-fetch
. Para mais informações, visite a documentação do node-fetch. Este código pode ser diferente dependendo do proxy escolhido. Consulte a documentação oficial da Bright Data para as informações mais recentes.
Melhores Práticas da Fetch API
Ao fazer requisições com a Fetch API, siga estas práticas recomendadas para melhorar a eficiência e o desempenho:
Respostas em Cache
Para reduzir a carga nos servidores e melhorar a experiência geral do usuário, você pode usar mecanismos de cache que armazenam dados frequentemente requisições, evitando chamadas redundantes ao servidor. Aqui está um exemplo que verifica se seus dados já estão em cache antes de fazer uma requisição de rede:
const cache = new Map();
async function fetchWithCache(url) {
if (cache.has(url)) {
console.log("Fetching from cache:", url);
return cache.get(url);
}
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
cache.set(url, data);
console.log("Fetched and cached:", url);
return data;
} catch (error) {
console.error("Fetch error:", error);
throw error;
}
}
fetchWithCache("https://jsonplaceholder.typicode.com/posts")
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));
Prevenir requisições desnecessárias para dados já em cache pode melhorar o desempenho e reduzir os tempos de carregamento.
Tratamento de Timeout
Configurar alguns timeouts pode evitar que suas requisições de Fetch permaneçam indefinidamente. Você pode cancelar requisições que ultrapassam uma duração especificada usando o AbortController
. No exemplo a seguir, o timeout é definido para três segundos, enquanto o valor padrão de timeout é cinco segundos:
async function fetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => {
console.warn("Fetch request timed out:", url);
controller.abort();
}, timeout);
try {
const response = await fetch(url, { signal: controller.signal });
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("Fetch timeout or error:", error);
throw error;
}
}
fetchWithTimeout("https://jsonplaceholder.typicode.com/posts", 3000)
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));
Isso garante que requisições que ultrapassem o timeout especificado sejam anuladas, enquanto outros erros são tratados adequadamente.
Limitação de Requisições
Para evitar que suas APIs sejam sobrecarregadas com requisições, você deve implementar throttling para controlar a frequência das requisições. Assim, você deve limitar o número de requisições que podem ser feitas em um determinado período de tempo. O exemplo a seguir cria uma função de throttle
que garante que uma função seja executada no máximo uma vez a cada intervalo (limit
) especificado.
function throttle(func, limit) {
let lastFunc;
let lastRan;
return function (...args) {
const context = this;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function () {
if (Date.now() - lastRan >= limit) {
func.apply(context, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
const throttledFetch = throttle(async (url) => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log("Throttled fetch data:", data);
} catch (error) {
console.error("Throttled fetch error:", error);
}
}, 2000);
throttledFetch("https://jsonplaceholder.typicode.com/posts");
console.log("Fetching again in 2 seconds...");
throttledFetch("https://jsonplaceholder.typicode.com/posts");
A função throttledFetch
usa a ferramenta de throttle
para controlar as requisições à API. Ela garante que chamadas repetidas para buscar dados de uma URL sejam espaçadas por pelo menos dois segundos. Isso evita chamadas redundantes ou excessivas à API, trata erros e registra os dados recuperados.
Conclusão
A Fetch API simplifica as operações assíncronas e o manuseio de dados em aplicações web modernas. No entanto, desafios como bloqueios de IP, limites de taxa e CAPTCHAs podem surgir ao lidar com requisições em grande escala ou geolocalizadas.
As APIs de Raspagem e o Navegador de Raspagem da Bright Data oferecem soluções poderosas para esses desafios. As APIs de Raspagem permitem uma extração de dados sem interrupções, contornando medidas anti-raspagem, enquanto o Navegador de Raspagem lida com conteúdo dinâmico e pesado em JavaScript de forma eficiente. Essas ferramentas garantem uma coleta de dados segura, escalável e confiável, mesmo para os sites mais complexos.
Não é necessário cartão de crédito