La API Fetch es el estándar moderno para realizar solicitudes de red en JavaScript. Proporciona una alternativa más limpia, potente y basada en promesas frente al antiguo XMLHttpRequest.
1. Funcionamiento
Cuando llamas a fetch(), estás iniciando un proceso asíncrono. En lugar de bloquear tu código mientras espera la respuesta del servidor, fetch() devuelve una Promesa.
Paso 1: Llamas a fetch(url)
Paso 2: Devuelve inmediatamente una Promesa
Paso 3: La Promesa se resuelve en un objeto Response tan pronto como el servidor empieza a responder (incluso si es un error 404)
Paso 4: Analizas esa respuesta (por ejemplo, como JSON o texto) para obtener los datos reales
2. Una solicitud GET básica
Por defecto, fetch realiza una solicitud GET. Aquí tienes el patrón moderno usando async/await
async function getPlayerData() {
const url = "https://api.example.com/players/1";
try {
const response = await fetch(url);
// CRÍTICO: fetch solo falla en errores de red.
// ¡Debes verificar response.ok para errores 404 o 500!
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error("Error en fetch:", error);
}
}
3. Peticiones GET con Parámetros de Consulta (Query Params)
Los parámetros de consulta se añaden al final de la URL. Aunque puedes concatenarlos manualmente (ej. ?id=5&user=gemini), el objeto URLSearchParams es la forma moderna y segura de gestionar la codificación.
async function buscarUsuarios(categoria, limite) {
const baseURL = "https://api.ejemplo.com/search";
// URLSearchParams maneja automáticamente caracteres especiales y formato
const params = new URLSearchParams({
type: categoria,
count: limite,
sort: "desc"
});
const response = await fetch(`${baseURL}?${params.toString()}`);
return await response.json();
}
4. Enviando datos (Solicitud POST)
Para enviar datos a un servidor, pasas un objeto opcional “init” como segundo argumento. Este objeto define el método, encabezados y el cuerpo de la solicitud.
A. Enviando JSON (El Estándar)
Al enviar JSON, debes configurar explícitamente el encabezado Content-Type para que el servidor sepa cómo interpretar la cadena de texto que estás enviando.
async function postNewUser(userData) {
const response = await fetch("https://api.example.com/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(userData), // Los datos deben convertirse a string
});
return response.json();
}
B. Enviando Datos de Formulario (FormData)
Al usar el objeto FormData, no debes configurar el encabezado Content-Type manualmente. El navegador lo hará por ti, incluyendo el “boundary” necesario para separar los campos.
const enviarFormulario = async (elementoForm) => {
const formData = new FormData(elementoForm); // Captura todos los inputs por su atributo 'name'
const response = await fetch("/api/enviar", {
method: "POST",
body: formData // ¡No se necesitan encabezados!
});
};
C. Enviando Imágenes (Blobs/Archivos)
Para subir un archivo (como una imagen de un input tipo file), puedes adjuntarlo a un FormData. Esta es la mejor opción si necesitas enviar metadatos (como el nombre de usuario) junto con la imagen.
const subirImagen = async (inputArchivo) => {
const archivo = inputArchivo.files[0];
const formData = new FormData();
formData.append("foto_perfil", archivo);
formData.append("usuario", "newUser");
const response = await fetch("/api/upload", {
method: "POST",
body: formData
});
if (response.ok) alert("¡Subida exitosa!");
};
D. Trabajando con Blobs (Imágenes y Archivos)
Si obtienes una imagen mediante .blob(), no puedes mostrarla directamente como texto. Debes crear una URL temporal usando URL.createObjectURL().
async function mostrarFotoPerfil() {
const response = await fetch("/imagenes/avatar.jpg");
const blob = await response.blob();
// Crea una URL temporal que representa el archivo
const urlImagen = URL.createObjectURL(blob);
// La asignamos a una etiqueta <img>
document.querySelector("#miImagen").src = urlImagen;
}
4. Puntos clave
Propiedad “ok”:
La promesa de fetch() solo falla si hay un error de red (como estar sin conexión). Si el servidor responde con un error 404 o 500, la promesa se resuelve correctamente. Debes verificar manualmente response.ok.
Consumo del cuerpo:
Métodos como .json(), .text() y .blob() también devuelven promesas porque la lectura del cuerpo de la respuesta es un proceso asíncrono.
CORS (Cross-Origin Resource Sharing):
Fetch sigue el protocolo CORS. Si intentas obtener datos de un dominio diferente, ese servidor debe permitir explícitamente tu dominio mediante encabezados HTTP específicos.
5. Manejo de la Respuesta
Cuando fetch() se resuelve, devuelve un objeto Response. Este objeto es como un contenedor de envío sellado: sabes que llegó, pero debes usar un método específico para “abrir” el contenido según lo que haya dentro, puedes extraer los datos usando:
Referencia rápida: Métodos de Response
response.json()– Convierte el contenido en un objeto JSONresponse.text()– Devuelve el contenido como texto planoresponse.blob()– Se usa para imágenes o archivosresponse.formData()– Se usa para datos de formularios multipart
Nota importante: Solo puedes usar uno de estos métodos en una misma respuesta. Una vez que el cuerpo se lee, se considera “consumido”.
| Método | Mejor uso para… | Ejemplo de uso |
.json() | APIs REST que devuelven datos estructurados. | const data = await response.json(); |
.text() | Fragmentos de HTML, archivos CSV o mensajes de texto plano. | const html = await response.text(); |
.blob() | Datos binarios puros como imágenes, PDFs o archivos de audio. | const imagen = await response.blob(); |
.formData() | Poco común en Fetch, se usa si el servidor devuelve multipart/form-data. | const form = await response.formData(); |

