Volver al inicio
Lección 13

📡 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:

get-request.jsjavascript
1// 1. Crear el objeto XMLHttpRequest
2const xhr = new XMLHttpRequest();
3
4// 2. Configurar la petición
5xhr.open('GET', 'https://jsonplaceholder.typicode.com/users/1');
6
7// 3. Definir qué hacer cuando llegue la respuesta
8xhr.onreadystatechange = function() {
9 // readyState 4 = petición completada
10 if (xhr.readyState === 4) {
11 // status 200 = respuesta exitosa
12 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ón
22xhr.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
readystate-status.jsjavascript
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:

post-request.jsjavascript
1const xhr = new XMLHttpRequest();
2
3// Configurar petición POST
4xhr.open('POST', 'https://jsonplaceholder.typicode.com/users');
5
6// Especificar que enviamos JSON
7xhr.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 enviar
17const nuevoUsuario = {
18 name: 'Ana García',
19 email: 'ana@example.com'
20};
21
22// Enviar datos como JSON
23xhr.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:

error-handling.jsjavascript
1const xhr = new XMLHttpRequest();
2xhr.open('GET', 'https://jsonplaceholder.typicode.com/users/1');
3
4// Éxito
5xhr.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 segundos
25xhr.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:

callback-hell.jsjavascript
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 usuario
8 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 post
14 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 === 4 y xhr.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

XMLHttpRequest es la forma clásica de hacer peticiones HTTP
Necesita readyState === 4 y status === 200 para verificar éxito
Usa onreadystatechange o onload para manejar respuestas
Para POST necesitas setRequestHeader y JSON.stringify
Es complejo y verboso, por eso surgió Fetch API
Importante conocerlo para entender código antiguo

Próxima lección: Aprenderemos Fetch API y async/await, la forma moderna y elegante de hacer peticiones.