L54 - Fetch API
🧠 Concepto
Section titled “🧠 Concepto”fetch() es una API nativa del navegador (y disponible en Node.js desde v18+) para realizar peticiones HTTP. Devuelve una Promise que se resuelve con un objeto Response. Es la forma moderna y estándar de hacer peticiones AJAX, reemplazando a XMLHttpRequest.
💻 Petición GET básica
Section titled “💻 Petición GET básica”fetch('https://api.ejemplo.com/usuarios') .then(response => { // Response no es el JSON, es un objeto con metadatos return response.json(); // devuelve otra Promise }) .then(usuarios => { console.log(usuarios); }) .catch(error => { console.error('Error de red:', error); });Con async/await:
async function obtenerUsuarios() { const response = await fetch('https://api.ejemplo.com/usuarios'); const usuarios = await response.json(); return usuarios;}📝 El objeto Response
Section titled “📝 El objeto Response”fetch('/api/datos') .then(res => { console.log(res.status); // 200, 404, 500... console.log(res.statusText); // 'OK', 'Not Found'... console.log(res.ok); // true si status 200-299 console.log(res.headers); // Headers de la respuesta console.log(res.url); // URL final (tras redirecciones) });Métodos para extraer el body
Section titled “Métodos para extraer el body”| Método | Uso |
|---|---|
res.json() | Parsa como JSON |
res.text() | Devuelve texto plano |
res.blob() | Para binarios (imágenes, archivos) |
res.formData() | Para datos de formulario |
res.arrayBuffer() | Para buffers binarios |
⚠️ Manejo de errores
Section titled “⚠️ Manejo de errores”Cuidado: fetch solo rechaza la Promise en caso de error de red (sin conexión, DNS falla, timeout). Un código HTTP 404 o 500 NO rechaza la Promise:
// Esto NO funciona como esperasfetch('/api/no-existe') .then(res => res.json()) .catch(err => { // Solo si hay error de red });La solución es verificar response.ok:
async function fetchSeguro(url) { const res = await fetch(url); if (!res.ok) { throw new Error(`HTTP error! status: ${res.status}`); } return res.json();}
try { const datos = await fetchSeguro('/api/no-existe');} catch (err) { console.error('Petición falló:', err.message);}💻 POST con fetch
Section titled “💻 POST con fetch”Para enviar datos al servidor:
const usuario = { nombre: 'Ana', email: 'ana@ejemplo.com'};
const response = await fetch('/api/usuarios', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer token123' }, body: JSON.stringify(usuario)});
if (!response.ok) { throw new Error(`Error ${response.status}`);}
const resultado = await response.json();console.log('Usuario creado:', resultado);Otros métodos HTTP
Section titled “Otros métodos HTTP”// PUT (actualizar)fetch('/api/usuarios/1', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ nombre: 'Ana Updated' })});
// DELETEfetch('/api/usuarios/1', { method: 'DELETE' });
// PATCH (actualización parcial)fetch('/api/usuarios/1', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ nombre: 'Ana Patch' })});📝 Enviar FormData (formularios, archivos)
Section titled “📝 Enviar FormData (formularios, archivos)”const formData = new FormData();formData.append('nombre', 'Ana');formData.append('avatar', archivoInput.files[0]);
const response = await fetch('/api/usuarios', { method: 'POST', body: formData // No pongas Content-Type, fetch lo pone solo});🎯 Opciones avanzadas
Section titled “🎯 Opciones avanzadas”const response = await fetch(url, { method: 'GET', // o POST, PUT, DELETE... headers: { ... }, body: ..., signal: AbortSignal.timeout(5000), // timeout 5s cache: 'no-cache', // no-store, reload, force-cache... credentials: 'include', // enviar cookies cross-origin mode: 'cors', // same-origin, no-cors redirect: 'follow' // manual, error});Abortar una petición
Section titled “Abortar una petición”const controller = new AbortController();
// Cancelar después de 3ssetTimeout(() => controller.abort(), 3000);
try { const res = await fetch(url, { signal: controller.signal });} catch (err) { if (err.name === 'AbortError') { console.log('Petición cancelada'); }}⚠️ Errores comunes
Section titled “⚠️ Errores comunes”- Olvidar
awaitenres.json():res.json()devuelve una Promise. - No verificar
response.ok: los 404/500 pasan desapercibidos. - Usar
fetchcon URLs relativas mal formadas: asegúrate de que la ruta sea correcta. - Olvidar
JSON.stringify()en el body: el body debe ser un string, no un objeto.
🎯 Regla de oro: siempre envuelve
fetchen una función que verifiqueresponse.oky maneje errores de red + HTTP por separado.