Axios: Guía Completa para Peticiones HTTP
Publicado el 1 de octubre, 2025 • 20 min de lectura
Axios es la librería más popular para hacer peticiones HTTP en JavaScript. Si has usado fetch y te has encontrado escribiendo el mismo código repetitivo una y otra vez, Axios es la solución.
¿Qué es Axios?
Axios es una librería de JavaScript que hace que trabajar con peticiones HTTP sea más fácil y consistente. Es como fetch, pero con superpoderes.
Piensa en Axios como un asistente personal:
- Fetch: Tienes que hacer todo manualmente (verificar errores, convertir JSON, configurar headers cada vez)
- Axios: Tu asistente hace el trabajo pesado automáticamente (convierte JSON, maneja errores mejor, configuración reutilizable)
¿Por qué usar Axios en lugar de fetch?
Comparemos las dos opciones con un ejemplo real:
Con fetch (nativo)
async function obtenerUsuario(id) {
try {
const response = await fetch(`https://api.ejemplo.com/usuarios/${id}`)
// Verificar manualmente si fue exitoso
if (!response.ok) {
throw new Error(`Error: ${response.status}`)
}
// Convertir manualmente a JSON
const usuario = await response.json()
return usuario
} catch (error) {
console.error('Error:', error)
throw error
}
}
Con Axios
async function obtenerUsuario(id) {
try {
const response = await axios.get(`https://api.ejemplo.com/usuarios/${id}`)
// Los datos ya están en formato JSON
return response.data
} catch (error) {
// Axios automáticamente lanza error si status no es 2xx
console.error('Error:', error.message)
throw error
}
}
Ventajas de Axios:
- Convierte JSON automáticamente (no necesitas
.json()
) - Lanza errores automáticamente en status codes 4xx/5xx
- Sintaxis más corta y limpia
- Interceptors (interceptores) para transformar peticiones/respuestas
- Cancelación de peticiones más simple
- Timeouts (límite de tiempo) integrados
- Funciona igual en navegador y Node.js
- Transformación automática de datos
- Protección contra CSRF (Cross-Site Request Forgery)
- Soporte de progress (progreso) de subida/descarga
¿Cuándo usar cada uno?
Usa fetch si quieres evitar dependencias externas y tus necesidades son simples.
Usa Axios si necesitas funcionalidades avanzadas, mejor manejo de errores, o harás muchas peticiones HTTP en tu proyecto.
Instalación
Axios es una librería externa, así que necesitas instalarla:
Con npm
npm install axios
Con yarn
yarn add axios
Con pnpm
pnpm add axios
Desde CDN (para HTML)
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
Importar en tu código
// ES6 modules
import axios from 'axios'
// CommonJS (Node.js antiguo)
const axios = require('axios')
Sintaxis básica
GET: Obtener datos
La forma más simple de hacer una petición:
// Promesas con .then()
axios.get('https://jsonplaceholder.typicode.com/users')
.then(response => {
console.log(response.data)
})
.catch(error => {
console.error('Error:', error)
})
// Async/await (recomendado)
async function obtenerUsuarios() {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/users')
console.log(response.data)
} catch (error) {
console.error('Error:', error)
}
}
El objeto response:
const response = await axios.get('url')
console.log(response.data) // Los datos de la respuesta
console.log(response.status) // 200, 404, 500, etc.
console.log(response.statusText) // "OK", "Not Found", etc.
console.log(response.headers) // Headers de la respuesta
console.log(response.config) // Configuración de la petición
POST: Enviar datos
async function crearUsuario() {
try {
const response = await axios.post('https://jsonplaceholder.typicode.com/users', {
nombre: 'Ana García',
email: 'ana@ejemplo.com',
edad: 25
})
console.log('Usuario creado:', response.data)
} catch (error) {
console.error('Error:', error)
}
}
No necesitas JSON.stringify()
ni configurar Content-Type
manualmente. Axios lo hace automáticamente.
PUT: Actualizar datos completos
async function actualizarUsuario(id) {
try {
const response = await axios.put(`https://api.ejemplo.com/usuarios/${id}`, {
nombre: 'Ana García Actualizada',
email: 'ana.nueva@ejemplo.com',
edad: 26
})
console.log('Usuario actualizado:', response.data)
} catch (error) {
console.error('Error:', error)
}
}
PATCH: Actualizar datos parciales
async function actualizarEmail(id) {
try {
const response = await axios.patch(`https://api.ejemplo.com/usuarios/${id}`, {
email: 'nuevo@ejemplo.com' // Solo actualizar el email
})
console.log('Email actualizado:', response.data)
} catch (error) {
console.error('Error:', error)
}
}
DELETE: Eliminar datos
async function eliminarUsuario(id) {
try {
const response = await axios.delete(`https://api.ejemplo.com/usuarios/${id}`)
console.log('Usuario eliminado')
} catch (error) {
console.error('Error:', error)
}
}
Configuración de peticiones
Axios permite configurar muchos aspectos de tus peticiones:
Sintaxis extendida
const response = await axios({
method: 'post', // get, post, put, delete, etc.
url: 'https://api.ejemplo.com/usuarios',
data: { // Datos a enviar (body)
nombre: 'Ana',
email: 'ana@ejemplo.com'
},
headers: { // Headers personalizados
'Authorization': 'Bearer token123'
},
params: { // Query parameters (?clave=valor)
activo: true,
rol: 'admin'
},
timeout: 5000, // Timeout en milisegundos
responseType: 'json' // json, text, blob, etc.
})
Query parameters
Los query parameters son los parámetros que van en la URL después del ?
:
// Forma manual
const response = await axios.get('https://api.ejemplo.com/usuarios?edad=25&ciudad=Madrid')
// Forma con params (mejor)
const response = await axios.get('https://api.ejemplo.com/usuarios', {
params: {
edad: 25,
ciudad: 'Madrid'
}
})
// Ambas formas generan: /usuarios?edad=25&ciudad=Madrid
Headers personalizados
const response = await axios.get('https://api.ejemplo.com/datos', {
headers: {
'Authorization': 'Bearer mi-token-secreto',
'Accept': 'application/json',
'X-Custom-Header': 'valor-personalizado'
}
})
Timeout (límite de tiempo)
// Si tarda más de 5 segundos, lanza error
const response = await axios.get('https://api.ejemplo.com/datos', {
timeout: 5000 // 5 segundos
})
Instancias de Axios
En lugar de configurar cada petición, puedes crear una instancia con configuración predeterminada:
// Crear instancia con configuración base
const api = axios.create({
baseURL: 'https://api.ejemplo.com',
timeout: 5000,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token123'
}
})
// Usar la instancia
const usuarios = await api.get('/usuarios') // https://api.ejemplo.com/usuarios
const usuario = await api.get('/usuarios/1') // https://api.ejemplo.com/usuarios/1
const nuevo = await api.post('/usuarios', { datos }) // https://api.ejemplo.com/usuarios
Ventajas de las instancias:
- Configuración reutilizable
- URLs más cortas (solo necesitas la ruta, no la URL completa)
- Diferentes instancias para diferentes APIs
- Fácil de mantener
Ejemplo práctico: API de tienda online
// Crear instancia para tu API
const tiendaAPI = axios.create({
baseURL: 'https://api.mitienda.com',
timeout: 10000,
headers: {
'Content-Type': 'application/json'
}
})
// Funciones reutilizables
async function obtenerProductos() {
const response = await tiendaAPI.get('/productos')
return response.data
}
async function obtenerProducto(id) {
const response = await tiendaAPI.get(`/productos/${id}`)
return response.data
}
async function crearProducto(datos) {
const response = await tiendaAPI.post('/productos', datos)
return response.data
}
async function actualizarProducto(id, datos) {
const response = await tiendaAPI.put(`/productos/${id}`, datos)
return response.data
}
async function eliminarProducto(id) {
const response = await tiendaAPI.delete(`/productos/${id}`)
return response.data
}
// Usar las funciones
const productos = await obtenerProductos()
const producto = await obtenerProducto(1)
Interceptors (Interceptores)
Los interceptors son funciones que se ejecutan antes de enviar una petición o después de recibir una respuesta. Son muy útiles para:
- Añadir tokens de autenticación automáticamente
- Transformar datos antes de enviar
- Manejar errores globalmente
- Mostrar/ocultar indicadores de carga
- Logging de peticiones
Request Interceptor (antes de enviar)
// Crear instancia
const api = axios.create({
baseURL: 'https://api.ejemplo.com'
})
// Interceptor de petición (request)
api.interceptors.request.use(
(config) => {
// Hacer algo antes de enviar la petición
console.log('Enviando petición a:', config.url)
// Por ejemplo, añadir token de autenticación
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => {
// Manejar error de petición
return Promise.reject(error)
}
)
// Ahora todas las peticiones incluirán el token automáticamente
const datos = await api.get('/datos-protegidos')
Response Interceptor (después de recibir)
// Interceptor de respuesta (response)
api.interceptors.response.use(
(response) => {
// Hacer algo con la respuesta exitosa
console.log('Respuesta recibida:', response.status)
return response
},
(error) => {
// Manejar error de respuesta
if (error.response) {
// El servidor respondió con un status code fuera del rango 2xx
if (error.response.status === 401) {
console.log('No autorizado - redirigir a login')
// window.location.href = '/login'
} else if (error.response.status === 500) {
console.log('Error del servidor')
}
} else if (error.request) {
// La petición se hizo pero no hubo respuesta
console.log('Sin respuesta del servidor')
} else {
// Algo pasó al configurar la petición
console.log('Error:', error.message)
}
return Promise.reject(error)
}
)
Ejemplo completo: Autenticación automática
const api = axios.create({
baseURL: 'https://api.ejemplo.com',
timeout: 10000
})
// Añadir token a todas las peticiones
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem('auth_token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => Promise.reject(error)
)
// Manejar errores de autenticación globalmente
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Token expirado o inválido
localStorage.removeItem('auth_token')
window.location.href = '/login'
}
return Promise.reject(error)
}
)
// Todas las peticiones ahora:
// 1. Incluyen el token automáticamente
// 2. Redirigen a login si el token es inválido
const datosProtegidos = await api.get('/perfil')
Ejemplo: Loading global
let peticionesActivas = 0
api.interceptors.request.use(
(config) => {
peticionesActivas++
// Mostrar spinner de carga
document.getElementById('loading').style.display = 'block'
return config
},
(error) => Promise.reject(error)
)
api.interceptors.response.use(
(response) => {
peticionesActivas--
if (peticionesActivas === 0) {
// Ocultar spinner cuando no hay peticiones activas
document.getElementById('loading').style.display = 'none'
}
return response
},
(error) => {
peticionesActivas--
if (peticionesActivas === 0) {
document.getElementById('loading').style.display = 'none'
}
return Promise.reject(error)
}
)
Manejo de errores
Axios tiene un manejo de errores más robusto que fetch:
Estructura del error
try {
const response = await axios.get('https://api.ejemplo.com/datos')
} catch (error) {
if (error.response) {
// El servidor respondió con un status fuera del rango 2xx
console.log('Datos:', error.response.data)
console.log('Status:', error.response.status)
console.log('Headers:', error.response.headers)
} else if (error.request) {
// La petición se hizo pero no hubo respuesta
console.log('No hubo respuesta:', error.request)
} else {
// Algo pasó al configurar la petición
console.log('Error:', error.message)
}
console.log('Config:', error.config)
}
Manejo de diferentes status codes
async function obtenerDatos() {
try {
const response = await axios.get('https://api.ejemplo.com/datos')
return response.data
} catch (error) {
if (error.response) {
switch (error.response.status) {
case 400:
throw new Error('Petición inválida')
case 401:
throw new Error('No autorizado - inicia sesión')
case 403:
throw new Error('Acceso prohibido')
case 404:
throw new Error('Recurso no encontrado')
case 500:
throw new Error('Error del servidor')
default:
throw new Error(`Error: ${error.response.status}`)
}
} else if (error.request) {
throw new Error('No se pudo conectar al servidor')
} else {
throw new Error('Error al configurar la petición')
}
}
}
Configurar validación de status
Por defecto, Axios rechaza promesas en status codes fuera del rango 200-299. Puedes cambiar esto:
const response = await axios.get('https://api.ejemplo.com/datos', {
validateStatus: (status) => {
// Considerar exitoso si status es menor a 500
return status < 500
}
})
// Ahora 404, 401, etc. no lanzan error
if (response.status === 404) {
console.log('Recurso no encontrado')
}
Cancelar peticiones
Axios hace muy fácil cancelar peticiones:
Con AbortController (recomendado)
async function buscarDatos() {
const controller = new AbortController()
try {
const response = await axios.get('https://api.ejemplo.com/buscar', {
signal: controller.signal
})
console.log(response.data)
} catch (error) {
if (axios.isCancel(error)) {
console.log('Petición cancelada:', error.message)
} else {
console.error('Error:', error)
}
}
// Cancelar después de 5 segundos
setTimeout(() => controller.abort(), 5000)
}
Ejemplo práctico: Búsqueda con cancelación
let controladorActual = null
async function buscar(query) {
// Cancelar búsqueda anterior
if (controladorActual) {
controladorActual.abort()
}
// Crear nuevo controlador
controladorActual = new AbortController()
try {
const response = await axios.get('https://api.ejemplo.com/buscar', {
params: { q: query },
signal: controladorActual.signal
})
mostrarResultados(response.data)
} catch (error) {
if (!axios.isCancel(error)) {
console.error('Error:', error)
}
}
}
// En un input de búsqueda
input.addEventListener('input', (e) => {
buscar(e.target.value)
})
Peticiones paralelas
Hacer múltiples peticiones al mismo tiempo:
Con Promise.all
async function obtenerTodosDatos() {
try {
const [usuarios, posts, comentarios] = await Promise.all([
axios.get('https://jsonplaceholder.typicode.com/users'),
axios.get('https://jsonplaceholder.typicode.com/posts'),
axios.get('https://jsonplaceholder.typicode.com/comments')
])
console.log('Usuarios:', usuarios.data.length)
console.log('Posts:', posts.data.length)
console.log('Comentarios:', comentarios.data.length)
} catch (error) {
console.error('Error:', error)
}
}
Con axios.all (deprecated pero aún funciona)
axios.all([
axios.get('url1'),
axios.get('url2'),
axios.get('url3')
])
.then(axios.spread((response1, response2, response3) => {
console.log(response1.data)
console.log(response2.data)
console.log(response3.data)
}))
Subir archivos
Axios hace fácil subir archivos:
Subir un archivo
async function subirArchivo(archivo) {
const formData = new FormData()
formData.append('archivo', archivo)
formData.append('descripcion', 'Mi archivo')
try {
const response = await axios.post('https://api.ejemplo.com/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: (progressEvent) => {
const porcentaje = (progressEvent.loaded / progressEvent.total) * 100
console.log(`Subiendo: ${porcentaje.toFixed(2)}%`)
}
})
console.log('Archivo subido:', response.data.url)
} catch (error) {
console.error('Error al subir:', error)
}
}
// Usar con input file
const input = document.querySelector('input[type="file"]')
input.addEventListener('change', (e) => {
const archivo = e.target.files[0]
subirArchivo(archivo)
})
Subir múltiples archivos
async function subirVariosArchivos(archivos) {
const formData = new FormData()
// Añadir múltiples archivos
for (let i = 0; i < archivos.length; i++) {
formData.append('archivos', archivos[i])
}
try {
const response = await axios.post('https://api.ejemplo.com/upload-multiple', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: (progressEvent) => {
const porcentaje = (progressEvent.loaded / progressEvent.total) * 100
actualizarBarraProgreso(porcentaje)
}
})
console.log('Archivos subidos:', response.data)
} catch (error) {
console.error('Error:', error)
}
}
Ejemplos prácticos completos
Ejemplo 1: Sistema de autenticación
const api = axios.create({
baseURL: 'https://api.ejemplo.com'
})
// Añadir token a todas las peticiones
api.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
}
)
// Login
async function login(email, password) {
try {
const response = await api.post('/auth/login', {
email,
password
})
// Guardar token
localStorage.setItem('token', response.data.token)
return response.data.usuario
} catch (error) {
if (error.response?.status === 401) {
throw new Error('Credenciales inválidas')
}
throw new Error('Error al iniciar sesión')
}
}
// Registro
async function registrar(datos) {
try {
const response = await api.post('/auth/registrar', datos)
// Guardar token
localStorage.setItem('token', response.data.token)
return response.data.usuario
} catch (error) {
if (error.response?.status === 400) {
throw new Error('Datos inválidos')
}
throw new Error('Error al registrar')
}
}
// Cerrar sesión
function logout() {
localStorage.removeItem('token')
window.location.href = '/login'
}
// Obtener perfil (requiere autenticación)
async function obtenerPerfil() {
try {
const response = await api.get('/perfil')
return response.data
} catch (error) {
if (error.response?.status === 401) {
logout()
}
throw error
}
}
Ejemplo 2: CRUD de productos
const api = axios.create({
baseURL: 'https://api.ejemplo.com/productos'
})
// CREATE - Crear producto
async function crearProducto(datos) {
try {
const response = await api.post('/', datos)
return response.data
} catch (error) {
throw new Error('Error al crear producto')
}
}
// READ - Obtener todos los productos
async function obtenerProductos(filtros = {}) {
try {
const response = await api.get('/', {
params: filtros // ?categoria=ropa&precio_max=100
})
return response.data
} catch (error) {
throw new Error('Error al obtener productos')
}
}
// READ - Obtener un producto
async function obtenerProducto(id) {
try {
const response = await api.get(`/${id}`)
return response.data
} catch (error) {
if (error.response?.status === 404) {
throw new Error('Producto no encontrado')
}
throw new Error('Error al obtener producto')
}
}
// UPDATE - Actualizar producto
async function actualizarProducto(id, datos) {
try {
const response = await api.put(`/${id}`, datos)
return response.data
} catch (error) {
throw new Error('Error al actualizar producto')
}
}
// DELETE - Eliminar producto
async function eliminarProducto(id) {
try {
await api.delete(`/${id}`)
return true
} catch (error) {
throw new Error('Error al eliminar producto')
}
}
// Usar las funciones
async function ejemplo() {
// Crear
const nuevo = await crearProducto({
nombre: 'Camisa',
precio: 25,
stock: 100
})
// Leer todos con filtros
const productos = await obtenerProductos({
categoria: 'ropa',
precio_max: 50
})
// Leer uno
const producto = await obtenerProducto(1)
// Actualizar
const actualizado = await actualizarProducto(1, {
precio: 30
})
// Eliminar
await eliminarProducto(1)
}
Ejemplo 3: Buscador con debounce
let timeoutId = null
let controladorBusqueda = null
async function buscar(query) {
// Limpiar timeout anterior
if (timeoutId) {
clearTimeout(timeoutId)
}
// Cancelar búsqueda anterior
if (controladorBusqueda) {
controladorBusqueda.abort()
}
// Esperar 500ms antes de buscar (debounce)
timeoutId = setTimeout(async () => {
if (query.length < 3) {
mostrarResultados([])
return
}
controladorBusqueda = new AbortController()
try {
const response = await axios.get('https://api.ejemplo.com/buscar', {
params: { q: query },
signal: controladorBusqueda.signal
})
mostrarResultados(response.data)
} catch (error) {
if (!axios.isCancel(error)) {
console.error('Error en búsqueda:', error)
mostrarResultados([])
}
}
}, 500)
}
// En el input
const input = document.getElementById('busqueda')
input.addEventListener('input', (e) => {
buscar(e.target.value)
})
function mostrarResultados(resultados) {
const contenedor = document.getElementById('resultados')
contenedor.innerHTML = ''
resultados.forEach(resultado => {
const div = document.createElement('div')
div.textContent = resultado.nombre
contenedor.appendChild(div)
})
}
Ejemplo 4: Paginación
async function cargarProductos(pagina = 1) {
const contenedor = document.getElementById('productos')
contenedor.innerHTML = '<p>Cargando...</p>'
try {
const response = await axios.get('https://api.ejemplo.com/productos', {
params: {
pagina: pagina,
limite: 20
}
})
const { datos, paginaActual, totalPaginas } = response.data
// Mostrar productos
contenedor.innerHTML = ''
datos.forEach(producto => {
const div = document.createElement('div')
div.innerHTML = `
<h3>${producto.nombre}</h3>
<p>$${producto.precio}</p>
`
contenedor.appendChild(div)
})
// Mostrar botones de paginación
crearBotonesPaginacion(paginaActual, totalPaginas)
} catch (error) {
contenedor.innerHTML = '<p>Error al cargar productos</p>'
}
}
function crearBotonesPaginacion(actual, total) {
const contenedor = document.getElementById('paginacion')
contenedor.innerHTML = ''
// Botón anterior
if (actual > 1) {
const btnAnterior = document.createElement('button')
btnAnterior.textContent = 'Anterior'
btnAnterior.onclick = () => cargarProductos(actual - 1)
contenedor.appendChild(btnAnterior)
}
// Número de página
const span = document.createElement('span')
span.textContent = `Página ${actual} de ${total}`
contenedor.appendChild(span)
// Botón siguiente
if (actual < total) {
const btnSiguiente = document.createElement('button')
btnSiguiente.textContent = 'Siguiente'
btnSiguiente.onclick = () => cargarProductos(actual + 1)
contenedor.appendChild(btnSiguiente)
}
}
// Cargar primera página
cargarProductos(1)
Axios en React
Hook personalizado
import { useState, useEffect } from 'react'
import axios from 'axios'
function useFetch(url) {
const [datos, setDatos] = useState(null)
const [cargando, setCargando] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
const controller = new AbortController()
async function cargar() {
try {
setCargando(true)
const response = await axios.get(url, {
signal: controller.signal
})
setDatos(response.data)
setError(null)
} catch (err) {
if (!axios.isCancel(err)) {
setError(err.message)
}
} finally {
setCargando(false)
}
}
cargar()
return () => controller.abort()
}, [url])
return { datos, cargando, error }
}
// Usar el hook
function ProductosComponent() {
const { datos, cargando, error } = useFetch('https://api.ejemplo.com/productos')
if (cargando) return <div>Cargando...</div>
if (error) return <div>Error: {error}</div>
return (
<div>
{datos.map(producto => (
<div key={producto.id}>{producto.nombre}</div>
))}
</div>
)
}
Diferencias: Fetch vs Axios
Comparación lado a lado:
Característica | Fetch | Axios |
---|---|---|
Nativo del navegador | ✓ Sí | ✗ No (dependencia) |
Conversión JSON automática | ✗ No (.json() ) | ✓ Sí |
Manejo de errores HTTP | ✗ Manual | ✓ Automático |
Interceptors | ✗ No | ✓ Sí |
Timeout | ✗ Manual con AbortSignal | ✓ Integrado |
Progress | ✗ Complejo | ✓ Simple |
Transformación de datos | ✗ Manual | ✓ Automática |
Node.js compatible | ✓ Desde v18 | ✓ Siempre |
Tamaño | 0 KB (nativo) | ~15 KB |
Errores comunes
Error 1: No usar try/catch
// ❌ Incorrecto
async function obtenerDatos() {
const response = await axios.get('url')
console.log(response.data)
}
// ✓ Correcto
async function obtenerDatos() {
try {
const response = await axios.get('url')
console.log(response.data)
} catch (error) {
console.error('Error:', error)
}
}
Error 2: Olvidar .data
// ❌ Incorrecto
const response = await axios.get('url')
return response // Retorna todo el objeto response
// ✓ Correcto
const response = await axios.get('url')
return response.data // Retorna solo los datos
Error 3: Configurar headers innecesarios en FormData
// ❌ Incorrecto
const formData = new FormData()
formData.append('archivo', archivo)
await axios.post('url', formData, {
headers: {
'Content-Type': 'multipart/form-data' // No necesario, se añade automáticamente
}
})
// ✓ Correcto
await axios.post('url', formData) // Axios configura el Content-Type automáticamente
Error 4: No cancelar peticiones
// ❌ Incorrecto: peticiones múltiples sin cancelar
function buscar(query) {
axios.get(`/buscar?q=${query}`)
.then(response => mostrarResultados(response.data))
}
input.addEventListener('input', (e) => {
buscar(e.target.value) // Múltiples peticiones simultáneas
})
// ✓ Correcto: cancelar petición anterior
let controller = null
async function buscar(query) {
if (controller) controller.abort()
controller = new AbortController()
const response = await axios.get(`/buscar?q=${query}`, {
signal: controller.signal
})
mostrarResultados(response.data)
}
Resumen
Puntos clave sobre Axios:
- Librería externa que simplifica peticiones HTTP
- Convierte JSON automáticamente
- Lanza errores en status codes 4xx/5xx
- Interceptors para transformar peticiones/respuestas
- Instancias con configuración reutilizable
- Cancelación de peticiones más simple
- Timeout integrado
- Progreso de subida/descarga
- Funciona igual en navegador y Node.js
- Mejor manejo de errores que fetch
Cuándo usar Axios:
- Necesitas funcionalidades avanzadas (interceptors, timeouts)
- Harás muchas peticiones HTTP en tu proyecto
- Quieres código más limpio y menos repetitivo
- Necesitas transformaciones automáticas
- Quieres mejor manejo de errores
Cuándo usar fetch:
- Proyecto simple con pocas peticiones
- Quieres evitar dependencias externas
- El tamaño del bundle es crítico
- Solo necesitas peticiones básicas GET/POST
Recursos adicionales:
Sobre el autor: Desarrollador especializado en JavaScript, React y NextJS. Creo contenido educativo en español para ayudar a la comunidad de desarrolladores.