Depuración7 min de lectura

Cómo corregir los errores "URI malformed" en JavaScript

Diagnostica y corrige el habitual error "URIError: URI malformed" en JavaScript con soluciones prácticas.

Entender el error URIError: URI Malformed

El error URIError: URI malformed se produce en JavaScript cuando intentas decodificar una cadena que contiene secuencias percent-encoded no válidas. Este error lo lanzan decodeURI() o decodeURIComponent() cuando se encuentran con un carácter codificado con un formato incorrecto.

Causas habituales

1. Signos de porcentaje sueltos

Un signo de porcentaje (%) que no va seguido exactamente de dos dígitos hexadecimales no es válido. Por ejemplo, %, %G o %2 (incompleto) provocarán todos este error.

// Estos lanzarán URIError
decodeURIComponent('%');        // % suelto
decodeURIComponent('%2');       // Secuencia incompleta
decodeURIComponent('%GH');      // Dígitos hexadecimales no válidos
decodeURIComponent('100%');     // % al final sin dígitos hexadecimales

2. Secuencias UTF-8 no válidas

Cuando los bytes percent-encoded no forman una secuencia de caracteres UTF-8 válida, el decodificador no puede convertirlos en una cadena. Esto puede ocurrir cuando los datos están corruptos o se codificaron usando una codificación de caracteres distinta.

3. Doble codificación

La doble codificación ocurre cuando una cadena ya codificada se vuelve a codificar. Por ejemplo, %20 (un espacio codificado) se convierte en %2520. Cuando intentas decodificar la cadena original, las secuencias pueden resultar no válidas.

Cómo corregirlo

Solución 1: usar try-catch

function safeDecode(str) {
  try {
    return decodeURIComponent(str);
  } catch (e) {
    // Devuelve la cadena original si la decodificación falla
    console.warn('Failed to decode:', str, e.message);
    return str;
  }
}

Solución 2: validar antes de decodificar

function isValidEncodedURI(str) {
  try {
    decodeURIComponent(str);
    return true;
  } catch {
    return false;
  }
}

function fixMalformedURI(str) {
  // Reemplaza los % sueltos por %25 (porcentaje codificado)
  return str.replace(/%(?![0-9A-Fa-f]{2})/g, '%25');
}

Solución 3: evitar la doble codificación

function smartEncode(str) {
  // Primero intenta decodificar: si tiene éxito, la cadena
  // ya está codificada
  try {
    const decoded = decodeURIComponent(str);
    // Si la decodificación cambió la cadena, estaba codificada
    if (decoded !== str) {
      return str; // Ya está codificada, devuélvela tal cual
    }
  } catch {
    // No es una cadena codificada válida, la codificamos
  }
  return encodeURIComponent(str);
}

Buenas prácticas de prevención

  • Usa siempre try-catch al decodificar URLs proporcionadas por el usuario o externas
  • Valida las URLs antes de procesarlas
  • Ten cuidado de no codificar dos veces los valores
  • Usa las APIs URL y URLSearchParams siempre que sea posible: gestionan la codificación correctamente
  • Sanea los valores de la cadena de consulta antes de codificarlos
  • Registra las URLs con formato incorrecto para facilitar la depuración

Artículos relacionados

Prueba nuestras herramientas gratuitas