📡 XMLHttpRequest (forma clásica)
Aprende la forma clásica de hacer peticiones HTTP desde JavaScript. Aunque hoy en día usamos Fetch API, es importante conocer XMLHttpRequest para entender código antiguo.
1. ¿Qué es XMLHttpRequest?
XMLHttpRequest (XHR) es la forma clásica de hacer peticiones HTTP desde JavaScript. Fue la primera manera de comunicarse con servidores sin recargar la página.
📌 Importante:
Aunque hoy en día usamos Fetch API, es importante conocer XMLHttpRequest porque:
- • Mucho código antiguo lo usa
- • Algunos navegadores muy viejos solo soportan XHR
- • Te ayuda a entender por qué Fetch es mejor
2. Petición GET básica
Para hacer una petición GET con XMLHttpRequest necesitamos varios pasos:
1// 1. Crear el objeto XMLHttpRequest2const xhr = new XMLHttpRequest();3 4// 2. Configurar la petición5xhr.open('GET', 'https://jsonplaceholder.typicode.com/users/1');6 7// 3. Definir qué hacer cuando llegue la respuesta8xhr.onreadystatechange = function() {9 // readyState 4 = petición completada10 if (xhr.readyState === 4) {11 // status 200 = respuesta exitosa12 if (xhr.status === 200) {13 const datos = JSON.parse(xhr.responseText);14 console.log('Usuario:', datos);15 } else {16 console.log('Error:', xhr.status);17 }18 }19};20 21// 4. Enviar la petición22xhr.send();Como ves, el código es bastante largo y complejo para algo tan simple como hacer una petición.
3. readyState y status
readyState (estado de la petición)
Indica en qué fase está la petición:
0 No iniciado 1 Conexión establecida 2 Petición recibida 3 Procesando 4 Completado ✓ status (código HTTP)
Indica el resultado de la petición:
200 OK (éxito) 404 No encontrado 500 Error del servidor 403 Prohibido 1const xhr = new XMLHttpRequest();2xhr.open('GET', 'https://jsonplaceholder.typicode.com/users/1');3 4xhr.onreadystatechange = function() {5 console.log('readyState:', xhr.readyState);6 7 if (xhr.readyState === 4) {8 console.log('status:', xhr.status);9 10 if (xhr.status === 200) {11 console.log('✓ Petición exitosa');12 } else if (xhr.status === 404) {13 console.log('✗ Recurso no encontrado');14 } else {15 console.log('✗ Error:', xhr.status);16 }17 }18};19 20xhr.send();4. Petición POST
Para enviar datos al servidor usamos el método POST:
1const xhr = new XMLHttpRequest();2 3// Configurar petición POST4xhr.open('POST', 'https://jsonplaceholder.typicode.com/users');5 6// Especificar que enviamos JSON7xhr.setRequestHeader('Content-Type', 'application/json');8 9xhr.onreadystatechange = function() {10 if (xhr.readyState === 4 && xhr.status === 201) {11 const respuesta = JSON.parse(xhr.responseText);12 console.log('Usuario creado:', respuesta);13 }14};15 16// Datos a enviar17const nuevoUsuario = {18 name: 'Ana García',19 email: 'ana@example.com'20};21 22// Enviar datos como JSON23xhr.send(JSON.stringify(nuevoUsuario)); Nota: status 201 significa
"Creado" - se usa cuando se crea un recurso nuevo.
5. Manejando errores
Con XMLHttpRequest, los errores se manejan con eventos adicionales:
1const xhr = new XMLHttpRequest();2xhr.open('GET', 'https://jsonplaceholder.typicode.com/users/1');3 4// Éxito5xhr.onload = function() {6 if (xhr.status === 200) {7 const datos = JSON.parse(xhr.responseText);8 console.log('✓ Datos recibidos:', datos);9 } else {10 console.log('✗ Error HTTP:', xhr.status);11 }12};13 14// Error de red (sin conexión, servidor caído, etc.)15xhr.onerror = function() {16 console.log('✗ Error de red - no se pudo conectar');17};18 19// Timeout (petición muy lenta)20xhr.ontimeout = function() {21 console.log('✗ La petición tardó demasiado');22};23 24// Configurar timeout de 5 segundos25xhr.timeout = 5000;26 27xhr.send();6. ¿Por qué XMLHttpRequest es complicado?
⚠️ Problemas de XMLHttpRequest:
- • Sintaxis verbosa: Necesitas muchas líneas para algo simple
- • Callbacks anidados: Si necesitas hacer varias peticiones, creas "callback hell"
- • Manejo de errores complejo: Múltiples eventos a controlar
- • No usa Promesas: No puedes usar async/await
- • Difícil de leer: El código es confuso y difícil de mantener
Ejemplo de callback hell con XMLHttpRequest:
1// Obtener usuario, luego sus posts, luego los comentarios...2const xhr1 = new XMLHttpRequest();3xhr1.open('GET', 'https://api.example.com/user/1');4xhr1.onload = function() {5 const usuario = JSON.parse(xhr1.responseText);6 7 // Ahora obtener los posts del usuario8 const xhr2 = new XMLHttpRequest();9 xhr2.open('GET', 'https://api.example.com/user/1/posts');10 xhr2.onload = function() {11 const posts = JSON.parse(xhr2.responseText);12 13 // Ahora obtener comentarios del primer post14 const xhr3 = new XMLHttpRequest();15 xhr3.open('GET', 'https://api.example.com/posts/' + posts[0].id + '/comments');16 xhr3.onload = function() {17 const comentarios = JSON.parse(xhr3.responseText);18 console.log('Comentarios:', comentarios);19 };20 xhr3.send();21 };22 xhr2.send();23};24xhr1.send();25 26// ¡Muy difícil de leer y mantener! 😰Por estas razones, JavaScript evolucionó hacia Fetch API y async/await, que veremos en la siguiente lección.
📝 Ejercicio práctico
Obtener y mostrar datos de usuario
Crea una petición GET a https://jsonplaceholder.typicode.com/users/5
y muestra en consola:
- • El nombre del usuario
- • Su email
- • El nombre de su ciudad
- • El nombre de su compañía
💡 Pistas:
- • Usa
xhr.readyState === 4yxhr.status === 200 - • Convierte la respuesta con
JSON.parse(xhr.responseText) - • Accede a las propiedades anidadas como
datos.address.city
💡 Ver estructura de datos de la API
1// La API devuelve algo como esto:2{3 "id": 5,4 "name": "Chelsey Dietrich",5 "email": "Lucio_Hettinger@annie.ca",6 "address": {7 "city": "Roscoeview"8 },9 "company": {10 "name": "Keebler LLC"11 }12}📚 Resumen
Próxima lección: Aprenderemos Fetch API y async/await, la forma moderna y elegante de hacer peticiones.