El HAR: compartir un problema de red sin regalar la sesión
Qué contiene exactamente un fichero HAR, las dos variantes de exportación, cómo leerlo cuando te lo mandan, y el riesgo de credenciales que casi nadie tiene en cuenta.
Cuando un problema de red solo ocurre en la máquina de otra persona, hay dos opciones: una videollamada con alguien leyendo columnas en voz alta, o un fichero que contiene la sesión entera y que puedes cargar en tu propio panel. El segundo camino es infinitamente mejor y tiene un peligro que casi nadie menciona: ese fichero contiene, literalmente, las credenciales con las que esa persona estaba autenticada.
- Exportar una sesión de red completa y elegir entre las dos variantes de exportación.
- Cargar un HAR ajeno en el panel y analizarlo como si fuera tuyo.
- Enumerar qué datos sensibles viajan en un HAR y cuáles no elimina la variante saneada.
- Procesar un HAR con código para responder preguntas que el panel no responde.
Qué es y qué contiene
Un HAR es un fichero JSON con un formato estándar que describe una sesión de red. Para cada petición guarda la URL, el método, todas las cabeceras de petición y de respuesta, los parámetros de consulta, las cookies, el cuerpo de la petición cuando lo hay, el desglose completo de tiempos, el tamaño, y con frecuencia el cuerpo de la respuesta. Es decir: lo mismo que ves en el panel, serializado.
La exportación se hace desde el menú contextual de la lista de peticiones o desde el botón de descarga de la barra del panel, y ofrece dos variantes.
La saneada elimina las cabeceras Cookie, Set-Cookie y Authorization. Es la que hay que usar por defecto y la que conviene pedir cuando alguien te va a mandar una.
La completa las incluye. Solo tiene sentido cuando el problema que estás diagnosticando es precisamente de cookies o de autenticación, y en ese caso el fichero es tan sensible como una contraseña.
La variante saneada elimina tres cabeceras. No toca las URLs ni los cuerpos. Un token en un parámetro de consulta, una clave de API en el cuerpo de un POST, un identificador de sesión devuelto en un JSON, el correo y el nombre del usuario en la respuesta de su perfil: todo eso sigue dentro. Un HAR saneado no es un HAR anónimo, es un HAR con tres cabeceras menos. Trátalo con el mismo cuidado que a la producción de la que salió.
Antes de grabar y después de recibir
Un HAR útil se prepara. Grabar sin preparación produce ficheros de decenas de megabytes con miles de peticiones irrelevantes en los que no se encuentra nada.
Antes de pedirle a alguien que grabe uno, dale estas instrucciones concretas y en este orden: abrir las DevTools en el panel de red, marcar la conservación del registro para que sobreviva a las navegaciones, vaciar la lista, reproducir el problema y solo el problema, y exportar inmediatamente. Ese “y solo el problema” es lo que separa un fichero útil de uno inservible. Si además puede anotar la hora exacta del momento en que vio el fallo, mejor: el HAR lleva marcas de tiempo absolutas y esa referencia permite localizar la petición en cuestión entre cientos.
Para cargar uno que te mandan, basta con arrastrarlo sobre el panel de red. A partir de ahí funciona todo: filtros, columnas, desglose de tiempos, cabeceras. Lo que no funciona es nada que requiera la página viva: no puedes reproducir la petición ni copiarla como comando, porque no hay ninguna página cargada detrás.
Hay una limitación que conviene conocer antes de perder tiempo buscando algo que no está: los cuerpos de las respuestas no siempre viajan en el fichero. Dependen de lo que el panel tuviera retenido en el momento de exportar, y las respuestas grandes o binarias con frecuencia se omiten. Si necesitas el cuerpo de una respuesta concreta, pídelo aparte.
Analizar un HAR con código
El panel es excelente para inspeccionar peticiones una a una y muy limitado para responder preguntas agregadas. Como el HAR es JSON, cualquier pregunta se responde con un poco de código. Este fragmento se pega en la consola de cualquier pestaña, pide el fichero, y saca las cuatro tablas que más veces hacen falta.
// Analizador de HAR: pegalo en la consola y elige el fichero
(() => {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.har,application/json';
input.onchange = async () => {
const har = JSON.parse(await input.files[0].text());
const es = har.log.entries;
console.log('Peticiones:', es.length, '| Paginas:', har.log.pages?.length ?? 0);
// 1. Las mas lentas
console.group('Las diez mas lentas');
console.table(es.slice().sort((a, b) => b.time - a.time).slice(0, 10).map(e => ({
url: e.request.url.split('?')[0].slice(-52),
metodo: e.request.method,
estado: e.response.status,
ms: Math.round(e.time),
esperaMs: Math.round(e.timings.wait ?? 0),
kb: Math.round((e.response.bodySize > 0 ? e.response.bodySize : 0) / 1024)
})));
console.groupEnd();
// 2. Los estados que no son de exito
const malos = es.filter(e => e.response.status >= 400 || e.response.status === 0);
console.group('Respuestas problematicas: ' + malos.length);
if (malos.length) console.table(malos.map(e => ({
url: e.request.url.slice(-60), estado: e.response.status, texto: e.response.statusText
})));
console.groupEnd();
// 3. Reparto del tiempo por origen
const porOrigen = {};
for (const e of es) {
const o = new URL(e.request.url).origin;
porOrigen[o] = porOrigen[o] || { origen: o, peticiones: 0, msTotal: 0, kb: 0 };
porOrigen[o].peticiones++;
porOrigen[o].msTotal += e.time;
porOrigen[o].kb += Math.max(0, e.response.bodySize) / 1024;
}
console.group('Reparto por origen');
console.table(Object.values(porOrigen)
.map(o => ({ ...o, msTotal: Math.round(o.msTotal), kb: Math.round(o.kb) }))
.sort((a, b) => b.msTotal - a.msTotal));
console.groupEnd();
// 4. Deteccion de secretos que la variante saneada no quita
const sospechosas = /(token|key|secret|passwd|password|session|auth|bearer|jwt)/i;
const fugas = [];
for (const e of es) {
for (const q of e.request.queryString || []) {
if (sospechosas.test(q.name)) fugas.push({ donde: 'query', campo: q.name, url: e.request.url.slice(-45) });
}
const cuerpo = e.request.postData?.text;
if (cuerpo && sospechosas.test(cuerpo)) fugas.push({ donde: 'cuerpo', campo: '(ver)', url: e.request.url.slice(-45) });
}
if (fugas.length) { console.warn('Posibles credenciales dentro del HAR:'); console.table(fugas); }
else console.log('No se han encontrado nombres de campo sospechosos.');
};
input.click();
})();
La cuarta tabla es la que conviene ejecutar antes de mandar un HAR, no después de recibirlo. Busca nombres de campo sospechosos en URLs y cuerpos, que es justo lo que la variante saneada no toca.
Cuándo compensa y cuándo no
Un HAR es la herramienta correcta para tres situaciones y solo para tres.
Un problema que no reproduces. Es su uso natural. La sesión de otra persona, en su red, con su versión, en su cuenta.
Un problema intermitente. Alguien graba durante el rato en que ocurre y tú analizas después, con calma, en lugar de intentar leer un panel que se mueve.
Una discusión con un tercero. Cuando hay que demostrar a un proveedor que su servicio tarda tres segundos, un HAR es un dato con marcas de tiempo y no una afirmación.
Fuera de esos casos hay opciones mejores. Para un problema tuyo y reproducible, el panel en vivo es superior porque permite reproducir peticiones, editar y volver a lanzar. Para vigilar el rendimiento de forma continua, un HAR no sirve: es una foto, y lo que hace falta es una serie temporal de campo.
Conviene ser explícito sobre lo que se está moviendo cuando se comparte uno de estos ficheros, porque la práctica habitual es adjuntarlo a un ticket público y olvidarse. Un HAR de una sesión autenticada contiene, en la variante completa, la cookie de sesión de esa persona: cualquiera que lo abra puede pegarla en su propio navegador y ser esa persona, hasta que la sesión caduque. Contiene también, con frecuencia, los datos personales que la aplicación devolvió sobre ella, el histórico de lo que consultó en esos minutos, su dirección de red aproximada a través de las cabeceras, y las URLs internas de servicios que quizá no sean públicos. Un ticket con un HAR adjunto en un sistema al que tiene acceso toda la empresa es una filtración pequeña y silenciosa, y si el sistema es público, es una filtración grande. Las tres reglas que hacen esto manejable son sencillas y hay que aplicarlas siempre. Primera: por defecto, la variante saneada, y la completa solo cuando el problema es de autenticación y sabiendo lo que se hace. Segunda: pásale el detector de secretos antes de adjuntarlo, porque los tokens en la URL son la fuga que ninguna variante elimina y son extraordinariamente comunes en integraciones de terceros. Tercera: si lo has generado en una sesión real con credenciales, cierra la sesión después, lo que invalida la cookie que acabas de meter en un fichero. Y una consideración final que cambia la política de un equipo entero: cuando pidas un HAR a un usuario de fuera de la organización, pídelo de una cuenta de prueba siempre que el problema se reproduzca en ella. La mayoría de los problemas de red no dependen de quién eres, y esa pregunta previa evita mover datos de un cliente por un canal de soporte.