URL Encode / Decode

Codifica y decodifica cadenas URL usando percent-encoding estándar.

toolboox.app/herramientas/url-encode-decode

Herramienta

Qué problema resuelve

Los parámetros de query con espacios, acentos o caracteres reservados rompen tus URLs.

Codificar una URL consiste en sustituir los caracteres que no pertenecen al conjunto seguro definido por el RFC 3986 por su secuencia `%XX` en hexadecimal, para que la URL viaje sin ambigüedad a través de navegadores, servidores y proxies. El error más habitual es aplicar `encodeURIComponent` a una URL completa (rompe `://` y las barras de la ruta) o, al contrario, usar `encodeURI` para un valor que va dentro de un parámetro de query (deja sin escapar el `&` y el `=`, mezclando el valor con la estructura de la query string). Este codificador y decodificador de URL aplica el algoritmo correcto según el contexto —una URL completa, un componente de ruta o un valor de query— directamente en el navegador.

Por qué existen los caracteres reservados y no reservados

El RFC 3986 divide los caracteres ASCII en reservados (tienen significado sintáctico dentro de la URL: : / ? # [ ] @ ! $ & ' ( ) * + , ; =) y no reservados (letras, dígitos, - _ . ~, que nunca necesitan codificarse). Cuando un carácter reservado forma parte del contenido de un valor —por ejemplo, un & dentro del texto de búsqueda de un usuario— y no de la estructura de la URL, debe codificarse como %26 para que el parser no lo confunda con el separador entre parámetros de la query string. Los caracteres fuera de ASCII (acentos, emoji, alfabetos no latinos) se codifican primero a UTF-8 y luego cada byte resultante se representa como %XX.

encodeURIComponent frente a encodeURI

encodeURIComponent codifica todos los caracteres reservados excepto - _ . ! ~ * ' ( ), y está pensado para un fragmento aislado: un valor de query, un segmento de ruta, un hash. encodeURI, en cambio, deja sin tocar los caracteres que forman la estructura de una URL completa (: / ? # & y similares) porque asume que le pasas la URL entera y no quieres romperla. El fallo clásico es usar encodeURI sobre un parámetro que el usuario ha escrito con un & o un =: como esos caracteres no se tocan, el navegador o el servidor los interpreta como parte de la estructura de la query string, no como contenido literal, y el parámetro llega truncado o corrupto al backend.

Codificación de la query string parámetro a parámetro

Una query string bien construida codifica cada clave y cada valor por separado con encodeURIComponent y luego los une manualmente con & y =, nunca al revés. Por ejemplo, para el valor precio: 10€ & envío gratis el resultado correcto es precio=10%E2%82%AC%20%26%20env%C3%ADo%20gratis (con el espacio como %20, el símbolo euro como su secuencia UTF-8 de tres bytes, y el & interno escapado para que no se confunda con el separador). Si en su lugar codificas la cadena precio=10€ & envío gratis entera con encodeURI, el = y el & internos sobreviven sin escapar y el parser de query string entiende dos parámetros donde debería haber uno solo.

El espacio: %20 frente a + según el contexto

En la parte de ruta y en fragmentos de una URL, el espacio se codifica como %20. Sin embargo, dentro de una query string con Content-Type: application/x-www-form-urlencoded (el formato que usan los formularios HTML clásicos y URLSearchParams), el espacio se representa históricamente como +, y un + literal debe entonces codificarse como %2B para no confundirse con un espacio. Esta es la razón por la que URLSearchParams de JavaScript produce + para los espacios mientras que encodeURIComponent produce %20: ambos son correctos, pero para contextos distintos, y mezclarlos en el mismo backend sin normalizar produce búsquedas o formularios que no encuentran coincidencias.

Doble codificación: un error silencioso y frecuente

Codificar dos veces una cadena que ya estaba codificada convierte cada % de una secuencia %XX en %2525, porque el propio carácter % es reservado y se codifica a %25. Esto ocurre con frecuencia en arquitecturas con varios saltos (un frontend que codifica, un proxy o CDN que reescribe la URL y la vuelve a codificar, y un backend que decodifica una sola vez): el resultado es que el backend recibe literalmente %25XX en lugar del carácter original y el dato llega corrupto. El síntoma característico en logs es encontrar secuencias %25 seguidas de dos caracteres hexadecimales donde se esperaba un carácter especial simple.

Emoji y caracteres multibyte en una URL

Un emoji como 🚀 no cabe en un solo punto de código ASCII: en UTF-8 ocupa cuatro bytes, y encodeURIComponent('🚀') produce %F0%9F%9A%80, la representación hexadecimal de esos cuatro bytes. Esto es distinto de un carácter acentuado como "ñ", que en UTF-8 ocupa dos bytes y se codifica como %C3%B1. Un error habitual es intentar decodificar una URL asumiendo Latin-1 en lugar de UTF-8: la secuencia de bytes es la misma, pero el resultado interpretado es una cadena de caracteres distinta y corrupta, típicamente visible como texto con acentos mal representados (mojibake).

Depurar una URL que llega rota al servidor

Cuando un backend recibe un parámetro truncado o con caracteres extraños, el primer paso es capturar la URL exacta que ha llegado (con curl -v o los logs del servidor web) y decodificarla manualmente segmento a segmento para localizar dónde se rompió la codificación. Si el problema aparece sólo con ciertos caracteres (&, =, #) casi siempre es un uso de encodeURI donde tocaba encodeURIComponent. Si aparece con acentos o emoji, revisa que todo el pipeline —frontend, proxy, backend— use UTF-8 de forma consistente, porque un solo eslabón con otra codificación (Latin-1, Windows-1252) corrompe el resultado aunque el resto de la cadena esté bien.

Salidas reales de ejemplo

encodeURIComponent aplicado a un valor de búsqueda
Entrada:  precio: 10€ & envío gratis
Salida:   precio%3A%2010%E2%82%AC%20%26%20env%C3%ADo%20gratis

El símbolo € y el espacio se codifican; el resultado es seguro para insertarlo como valor de un único parámetro de query.

Diferencia entre encodeURI y encodeURIComponent sobre la misma cadena
Entrada:            https://ejemplo.com/buscar?q=café & tapas
encodeURI:          https://ejemplo.com/buscar?q=caf%C3%A9%20&%20tapas
encodeURIComponent: https%3A%2F%2Fejemplo.com%2Fbuscar%3Fq%3Dcaf%C3%A9%20%26%20tapas

encodeURI conserva los caracteres estructurales de una URL; encodeURIComponent los escapa todos porque asume un fragmento aislado.

Doble codificación detectada en un log de acceso
GET /buscar?q=ni%2525C3%2525B1o%2520barato HTTP/1.1
# decodificar una vez -> q=ni%C3%B1o%20barato (todavía codificado)
# decodificar dos veces -> q=niño barato (valor correcto)

El '%25' delante de cada par hexadecimal indica que la cadena se codificó dos veces antes de llegar al servidor.

Funciones de codificación de URL en JavaScript

FunciónCaracteres que NO codificaUso correcto
encodeURIA-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , #Una URL completa que ya tiene su estructura definida
encodeURIComponentA-Z a-z 0-9 - _ . ! ~ * ' ( )Un único valor: parámetro de query, segmento de ruta, hash
URLSearchParamsIgual que encodeURIComponent, pero usa + para el espacioConstruir o parsear query strings de formularios

Cada función respeta un conjunto distinto de caracteres 'seguros' según el fragmento de URL al que se aplica.

Codificación de caracteres reservados frecuentes

CarácterCodificadoSignificado si va sin codificar
espacio%20Puede truncar la URL en algunos parsers antiguos
&%26Separador entre parámetros de la query string
=%3DSeparador entre clave y valor de un parámetro
#%23Inicio del fragmento (ancla) de la URL
%E2%82%ACCarácter no ASCII, tres bytes en UTF-8

Porcentaje hexadecimal resultante al aplicar encodeURIComponent a cada carácter.

Casos de uso comunes

  • Construir a mano una URL de compartir en redes sociales con texto y hashtags dinámicos
  • Depurar un parámetro de búsqueda que llega truncado al backend por un & sin codificar
  • Generar enlaces de reseteo de contraseña con un token que puede contener caracteres especiales
  • Insertar una URL completa como valor dentro de otro parámetro de query (redirect callbacks de OAuth)
  • Convertir nombres de archivo con acentos o espacios a rutas seguras para servir desde un CDN

Buenas prácticas

  • Usa `encodeURIComponent` para cualquier valor aislado y `encodeURI` sólo sobre una URL completa ya formada
  • Construye la query string parámetro a parámetro, nunca codificando la cadena `clave=valor&clave2=valor2` entera
  • No decodifiques una URL más veces de las que se codificó; comprueba si ves `%25` antes de decodificar de nuevo
  • Fuerza UTF-8 de forma consistente en frontend, proxy y backend para evitar mojibake con acentos y emoji
  • Si insertas una URL dentro de otra (redirect_uri de OAuth), codifica la URL interna completa como un único componente

Preguntas frecuentes

¿Por qué mi & desaparece al pasar un valor por la URL?

Casi siempre porque se codificó con `encodeURI` en lugar de `encodeURIComponent`. `encodeURI` no toca el `&` porque lo considera parte de la estructura de la URL, así que el parser de query string lo interpreta como separador de parámetros en vez de como contenido literal.

¿Es lo mismo %20 que + para representar un espacio?

Funcionalmente ambos representan un espacio, pero en contextos distintos: `%20` es el estándar RFC 3986 para rutas y fragmentos, mientras que `+` proviene del formato `application/x-www-form-urlencoded` de formularios HTML clásicos. Mezclarlos sin normalizar en el mismo backend puede producir búsquedas que no coinciden.

¿Cómo sé si una cadena está codificada dos veces?

La señal más clara es encontrar `%25` seguido de dos caracteres hexadecimales, porque `%25` es la codificación del propio símbolo `%`. Si ves `%2520` en vez de `%20`, esa cadena se codificó dos veces.

¿Los emoji necesitan un tratamiento especial al codificarlos?

No requieren nada especial más allá de UTF-8: `encodeURIComponent` los descompone en los cuatro bytes de su representación UTF-8 y los codifica como `%XX` cada uno, exactamente igual que con cualquier otro carácter no ASCII.

¿Debo codificar el dominio de una URL?

No con las funciones de porcentaje; un dominio con caracteres no ASCII (un dominio internacionalizado) se codifica con Punycode, un mecanismo distinto y específico para nombres de dominio, no con `encodeURIComponent`.