Errores de codificación de URL que los desarrolladores aún cometen (y corrigen)

URL son sutiles, persistentes y, a menudo, se descubren en producción. Un %20 mal colocado, un signo comercial con doble codificación o un + versus espacio confuso pueden interrumpir las llamadas API, corromper los datos de seguimiento y crear vulnerabilidades de seguridad. Arreglemos los más comunes.
Pruebe su codificación con nuestra herramienta URL Codificador/Decodificador: pegue cualquier cadena y vea el resultado codificado al instante.
encodeURI frente a encodeURIComponent
JavaScript tiene dos funciones de codificación integradas, y usar la incorrecta es la fuente número uno de errores:
| Función | Codifica | Conserva | Uso para |
|---|---|---|---|
encodeURI | Espacios, no ASCII | : / ? # [ ] @ ! $&'()*+,; = | Codificación de una URL completa |
encodeURIComponent | Todo lo anterior + : / ? #@! $&'()*+,; = | Solo - _ . ~ y alfanuméricos | Codificación de un valor de parámetro de consulta |
// INCORRECTO: encodeURI conserva y en los valores de consulta
url const = 'https://api.example.com/search?q=' + encodeURI('tom & jerry');
// Resultado: https://api.example.com/search?q=tom%20&%20jerry
// El & se conserva; ¡ahora parece un parámetro independiente! // CORRECTO
const url = 'https://api.example.com/search?q=' + encodeURIComponent('tom & jerry');
// Resultado: https://api.example.com/search?q=tom%20%26%20jerry
Regla general: Utilice encodeURIComponent para valores individuales. Utilice encodeURI solo cuando tenga una URL completa que solo necesite caracteres no ASCII codificados.
Errores de doble codificación
La doble codificación ocurre cuando una cadena ya codificada se codifica nuevamente:
const nombre = 'hola mundo';
const codificado = encodeURIComponent(nombre); // hola%20mundo
const duplicado = encodeURIComponent (codificado); // hola%2520world
// ¡%25 es la codificación del propio %!
Esto suele ocurrir cuando:
- Un marco codifica automáticamente los parámetros de consulta y usted también los codifica previamente
- Una URL se codifica antes de almacenarse y luego se codifica nuevamente cuando se recupera
- El middleware procesa la URL en varias capas y cada una agrega codificación
Detección
Busque %25 en las URL; casi siempre es una señal de doble codificación. La secuencia %2520 (espacio de doble codificación) es el indicador clásico.
La confusión + vs %20
En envíos de formularios HTML (application/x-www-form-urlencoded), los espacios se convierten en +. En la codificación porcentual estándar (RFC 3986), los espacios se convierten en %20.
Esto importa porque:
decodeURIComponentnot decodifica + de nuevo al espacio; lo deja como un literal +- Los marcos de backend pueden o no decodificar automáticamente
+ dependiendo del analizador - Si su API espera
%20 pero recibe +, la búsqueda de "coche+rojo" arroja resultados para "coche+rojo" (con un signo más literal) en lugar de "coche rojo"
// Decodificación segura que maneja tanto + como %20
función safeDecodeParam(valor) { return decodeURIComponent(value.replace(/\+/g, '%20'));
}
Casos extremos UTF-8
Caracteres no ASCII como é, ü, 日本語 y los emoji deben estar codificados en porcentaje como sus secuencias de bytes UTF-8:
encodeURIComponent('café') // caf%C3%A9
encodeURIComponent('日本語') // %E6%97%A5%E6%9C%AC%E8%AA%9E
encodeURIComponent('🔒') // %F0%9F%94%92
Los problemas surgen cuando:
- El servidor espera Latin-1 pero recibe UTF-8 (mojibake - caracteres confusos)
- Las columnas de la base de datos no están configuradas en UTF-8, lo que trunca silenciosamente los caracteres multibyte
- Los archivos de registro interpretan cadenas codificadas con un conjunto de caracteres incorrecto
Errores de URL de redireccionamiento y devolución de llamada
Las devoluciones de llamada de OAuth y las URL de redireccionamiento son especialmente propensas a errores de codificación:
// Construyendo una redirección OAuth
const redirecciónUri = 'https://myapp.com/callback?source=oauth';
URL de autenticación constante = `https://provider.com/auth?redirect_uri=${encodeURIComponent(redirectUri)}`;
// Correcto: toda la URL de devolución de llamada (¿incluida la suya propia?) está codificada como un único valor de parámetro
Errores comunes:
- No codificar el
redirect_uri en absoluto: el ? en la devolución de llamada divide la URL principal - Codificación parcial del
redirect_uri: codificación de la ruta pero no de la consulta - Codificación de la URL de autenticación completa en lugar de solo el valor del parámetro
Estos errores suelen crear vulnerabilidades de redireccionamiento abierto que los atacantes aprovechan para realizar phishing.
Lista de verificación de depuración
Cuando una URL no funciona como se esperaba, verifíquelas en orden:
- Busque %25: indica doble codificación
- Check + vs %20: ¿se manejan los espacios de manera consistente?
- Inspeccionar la solicitud sin procesar: use la pestaña Red de DevTools del navegador para ver la URL codificada real enviada
- Prueba con caracteres especiales - prueba
& =? # / en valores para ver si rompen la estructura de la URL - Check Content-Type: ¿el servidor analiza como
application/x-www-form-urlencoded o application/json? - Verificar decodificación en el servidor: registra los valores sin procesar y decodificados en el lado del servidor
Funciones auxiliares seguras
// Cree una cadena de consulta de forma segura
función buildQueryString(parámetros) { devolver objetos.entradas (parámetros) .map(([clave, valor]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}` ) .unirse('&');
} // Utilice URLSearchParams (navegadores modernos + Node.js)
parámetros constantes = nuevos URLSearchParams({ q: 'tom & jerry', page: '1' });
URL constante = `https://api.example.com/search?${params}`;
// Correcto: maneja la codificación automáticamente
Práctica recomendada: Utilice el constructor URLSearchParams o URL en lugar de la concatenación manual de cadenas. Manejan la codificación correctamente de forma predeterminada.
Preguntas frecuentes
¿Por qué + se convierte en un espacio?
Este es un legado de la codificación de formularios HTML (application/x-www-form-urlencoded), donde los espacios están codificados como +. En la codificación porcentual estándar (RFC 3986), los espacios son %20. La convención + solo se aplica a cadenas de consulta en envíos de formularios, no a segmentos de ruta u otras partes de URL.
¿Cómo codifico correctamente las URL anidadas?
Utilice encodeURIComponent en la URL interna antes de colocarla en el parámetro de consulta de la URL externa. Esto codifica caracteres como :/? que de otro modo se interpretarían como parte de la estructura de la URL externa.
¿Por qué las firmas se rompen después de la codificación de URL?
Las firmas se calculan sobre secuencias de bytes exactas. Si firma una cadena antes de codificarla (o después de decodificarla), pero la verifica en forma codificada (o viceversa), los bytes difieren y la firma falla. Normalice siempre la codificación antes de firmar.
Herramientas y artículos relacionados
- URL Codificador/Decodificador — codificación de prueba en tiempo real
- Errores de seguridad de JWT: la codificación también importa para el manejo de tokens
- Solución de discrepancia en la suma de comprobación: al codificar cambios, hashes de archivos corruptos