Todo lo que necesitas saber sobre XMLHttpRequest
XMLHttpRequest es un objeto nativo del navegador que permite hacer solicitudes HTTP desde JavaScript.
Con este objeto puedes cargar y descargar cualquier tipo de archivo pero también se puede utilizar para conseguir otras metas.
Se que hoy en día hay otro método más moderno que hace que el objeto XMLHttpRequest se quede obsoleto pero te voy a explicar 3 razones por las que XMLHttpRequest todavía se utiliza y no debes dejar de aprender su uso o al menos conocer su existencia.
XMLHttpRequest se usa por tres razones:
- Existen infinidad de scripts existentes que usan XMLHttpRequest.
- Mantener el funcionamiento de aplicaciones en navegadores antiguos.
- Rastreo del progreso de la subida de archivos.
Si algunos de estos motivos tiene mucho peso para ti, usa XMLHttpRequest sin duda.
De lo contrario, te recomiendo usar la técnica más moderna «fetch» de la que pronto hablaré en este blog.
Creación de las instancia
Puedes crear una instancia del objeto así:
const request = new XMLHttpRequest();
Es una llamada sencilla sin parámetros, ya que, el constructor no tiene argumentos.
Métodos principales
Lo primero que se suele hacer, justo después de crear la instancia del objeto es inicializarlo con la función:
request.open(method, URL, [async, user, password])
Este método open() especifica los parámetros principales para la petición:
- method: método HTTP. Usualmente «GET» o «POST».
URL: la URL a solicitar, una cadena, puede ser un objeto URL.
async: si se asigna explícitamente a false, entonces la petición será asincrónica. En caso contrario, petición síncrona. Por defecto, la petición es asíncrona.
user, password: usuario y contraseña para autenticación HTTP básica (si se requiere).
Para enviar la petición utiliza:
request.send();
Este método abre la conexión y envía la solicitud al servidor.
Se puede usar un parámetro opcional que permite enviar parámetros al servidor.
Por ejemplo, se puede usar este parámetro para enviar datos de un formulario al servidor usando el método POST.
Eventos más utilizados
Los eventos más más útiles son los siguientes:
- load: cuando la solicitud está; completa (incluso si el estado HTTP es 400 o 500), y la respuesta se descargó por completo.
error: cuando la solicitud no pudo ser realizada satisfactoriamente, ej. red caída o una URL inválida.
progress: se dispara periódicamente mientras la respuesta está siendo descargada, reporta cuánto se ha descargado.
Propiedades del resultado de la solicitud
Una vez el servidor ha respondido, es posible recibir el resultado mediante las siguientes propiedades del objeto request:
- status: Código del estado HTTP (un número): 200, 404, 403 y así por el estilo, puede ser 0 en caso de una falla no HTTP.
- statusText: Mensaje del estado HTTP (una cadena): usualmente OK para 200, Not Found para 404, Forbidden para 403 y así por el estilo.
- response (scripts antiguos deben usar responseText): El cuerpo de la respuesta del servidor.
- timeout: límite de tiempo en milisegundos.
Ejemplo:
request.responseType = 'json';
Tipo de respuesta
Con la propiedad request.responseType puedes asignar el formato de la respuesta:
- «» (default) – obtiene una cadena
- «text» – obtiene una cadena
- «arraybuffer» – obtiene un ArrayBuffer (para datos binarios, ve el capítulo ArrayBuffer, arrays binarios),
- «blob» – obtiene un Blob (para datos binarios, ver el capítulo Blob).
- «document» – obtiene un documento XML (puede usar XPath y otros métodos XML) o un documento HTML (en base al tipo MIME del dato recibido).
- «json» – obtiene un JSON (automáticamente analizado).
Estados de la solicitud
El objeto XMLHttpRequest cambia de estado a medida que avanza en su progreso.
El estado actual es accesible con request.readyState.
A continuación puedes ver todos los estados:
UNSENT = 0; // estado inicial
OPENED = 1; // llamada abierta
HEADERS_RECEIVED = 2; // cabeceras de respuesta recibidas
LOADING = 3; // la respuesta está cargando (un paquete de datos es recibido)
DONE = 4; // solicitud completa
Estos estados puedes seguirlos usando el evento request.readystatechange:
request.onreadystatechange = function() {
if (request.readyState == 3) {
//cargando
}
if (request.readyState == 4) {
//solicitud finalizada
}
};
Puedes encontrar oyentes del evento readystatechange en código realmente antiguo.
En el pasado no existía load y otros eventos.
Hoy en día, los manipuladores load/error/progress hacen obsoleto el evento readystatechange.
¿Cómo abortar solicitudes?
Puedes terminar la solicitud en cualquier momento con:
request.abort();
En este caso, request.status pasa a tener un valor de 0.
Gestión de cabeceras
XMLHttpRequest permite tanto enviar cabeceras personalizadas como leer cabeceras de la respuesta.
Existen 3 métodos para las cabeceras HTTP:
setRequestHeader(name, value): Asigna la cabecera de la solicitud con los valores name y value provistos.
Por ejemplo:
response.setRequestHeader('Content-Type', 'application/json');
Muchas cabeceras se administran exclusivamente por el navegador, ej. Referer y Host.
XMLHttpRequest no está permitido cambiarlos, por motivos de seguridad del usuario y la exactitud de la solicitud.
getResponseHeader(name): Obtiene la cabecera de la respuesta con el name dado (excepto Set-Cookie y Set-Cookie2).
Por ejemplo:
request.getResponseHeader('Content-Type');
getAllResponseHeaders(): Devuelve todas las cabeceras de la respuesta, excepto por Set-Cookie y Set-Cookie2.
Enviar un formulario
Teniendo como punto de partida el siguiente formulario:
let formData = new FormData(document.forms.register);
// agrega un campo más
formData.append("submitForm", 1);
// lo enviamos
let request = new XMLHttpRequest();
request.open("POST", "ajax.php");
request.send(formData);
request.onload = () => alert(request.response);
Otra opción muy utilizada es enviar el formulario con JSON:
let request = new XMLHttpRequest();
let json = JSON.stringify({
name: "Jose",
surname: "Aguilar"
});
request.open("POST", 'ajax.php')
request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
request.send(json);
Progreso de carga
Si tienes la intención de permitir la subida de algún fichero grande en tu servidor, seguramente puedas estar interesado en rastrear el progreso de la carga para mejorar la usabilidad mostrándole al usuario de que debe esperar a que se cargue el fichero para avanzar.
Hay otro objeto exclusivamente para rastrear los eventos de subida: request.upload.
Este genera eventos similares a request, pero request.upload se dispara solo en las subidas:
- loadstart – carga iniciada.
- progress – se dispara periódicamente durante la subida.
- abort – carga abortada.
- error – error no HTTP.
- load – carga finalizada con éxito.
- timeout – carga caducada (si la propiedad timeout está asignada).
- loadend – carga finalizada con éxito o error.
Ejemplos de manejadores:
request.upload.onprogress = function(event) {
alert(`Descargado ${event.loaded} de ${event.total} bytes`);
};
request.upload.onload = function() {
alert(`El archivo se cargó correctamente.`);
};
request.upload.onerror = function() {
alert(`Error durante la carga: ${xhr.status}`);
};
Conclusiones
Esta entrada es más bien teórica.
Ahora ya tienes todo lo que necesitas saber sobre XMLHttpRequest.
Dejo en tus manos que lo practiques.
En cualquier caso, en próximos tutoriales entraré en detalle con los ejemplos más prácticos mencionados aquí tales como el envío de un formulario o el rastreo de la carga de un fichero.
Deja una respuesta