Codificador / decodificador de URL

Codifica y decodifica URL, elige el ámbito componente o URL completa, y desglosa una URL en sus partes.

Para un valor suelto, como un parámetro de consulta. Escapa también / ? : @ & = + porque ahí son datos y no estructura.

Entrada
Salida

La salida aparecerá aquí

Para qué sirve la codificación en porcentaje

Una URL solo puede contener un conjunto reducido de caracteres: las letras A–Z y a–z, los dígitos, unos pocos signos como - . _ ~, y un conjunto de caracteres reservados que le dan forma a la dirección: / ? # & = : @ y algunos más. Cualquier otra cosa, desde un espacio hasta una palabra en hebreo o un emoji, tiene que representarse indirectamente. La codificación en porcentaje es esa representación: el carácter se convierte a sus bytes UTF-8 y cada byte se escribe como un signo de porcentaje seguido de dos dígitos hexadecimales. Un espacio pasa a ser %20, y א pasa a ser %D7%90.

Los caracteres reservados son el caso interesante. Son legales dentro de una URL, pero significan algo estructural: ? abre la consulta, & separa parámetros, = divide una clave de su valor. Cuando uno de esos caracteres forma parte de tus datos y no de la estructura, hay que codificarlo; de lo contrario el analizador del otro extremo lo leerá como puntuación y partirá tu valor en el sitio equivocado.

Componente o URL completa: la distinción que rompe enlaces

Esta es la fuente más común de errores con URL, y por eso esta herramienta te pide elegir un ámbito en lugar de adivinarlo.

  • El ámbito componente escapa también los delimitadores: / ? : @ & = + $ , y #. Úsalo para un solo dato —un término de búsqueda, un destino de redirección, un token— que se va a colocar dentro de una URL mayor.
  • El ámbito URL completa deja esos delimitadores intactos y solo escapa lo que es realmente ilegal, como los espacios y el texto no ASCII. Úsalo cuando ya tienes una dirección completa bien estructurada que solo necesita limpieza.

Equivocarse en cualquiera de las dos direcciones rompe algo. Codifica una URL entera en ámbito componente y cada barra y cada interrogante se convierten en %2F y %3F, produciendo una única cadena inservible. Codifica un valor suelto en ámbito URL completa y un ampersand dentro de él sobrevive como delimitador, de modo que una búsqueda de «gatos & perros» se convierte en silencio en dos parámetros y la segunda mitad de tu valor desaparece.

// El valor contiene un delimitador, así que debe escaparse:
const q = 'cats & dogs'
`/search?q=${encodeURIComponent(q)}`  // /search?q=cats%20%26%20dogs
`/search?q=${encodeURI(q)}`           // /search?q=cats%20&%20dogs  ✗

// Mejor aún: deja que la plataforma la construya
const url = new URL('https://example.com/search')
url.searchParams.set('q', 'cats & dogs')

Vale la pena adoptar ese último enfoque como costumbre. URL y URLSearchParams están integrados en todos los navegadores y en Node, y aplican la codificación correcta a cada parte por ti, lo que elimina la decisión en lugar de obligarte a acertar a mano cada vez.

Por qué un espacio es a veces + y a veces %20

Aquí operan dos especificaciones distintas, y discrepan exactamente en un carácter. El RFC 3986, que rige las URL en general, codifica el espacio como %20. El formato más antiguo application/x-www-form-urlencoded, que es lo que envían los formularios HTML y por tanto el aspecto que tienen la mayoría de las cadenas de consulta, lo codifica como +.

La trampa es que decodeURIComponent solo implementa la primera regla. Dale hello+world y recibirás hello+world de vuelta, con su más y todo: ni error, ni aviso, solo un valor sutilmente equivocado. Por eso esta herramienta ofrece la opción «tratar + como espacio» y te lo señala cuando tu entrada contiene un más y la opción está desactivada.

Ten en cuenta que URLSearchParams, que alimenta la tabla de desglose bajo la herramienta, sigue las reglas de formulario y sí convierte + en espacio. Así que la misma cadena de consulta puede decodificarse de forma distinta según la API que uses: deliberadamente, y correctamente, en ambos casos.

Una consecuencia que conviene recordar: si un más forma parte de verdad de tus datos —un número de teléfono, una expresión de filtro— hay que codificarlo como %2B. Un + literal en una cadena de consulta es ambiguo en el mejor de los casos y la mayoría de los analizadores lo leerán como un espacio.

Leer una URL

Pega una URL absoluta y la herramienta la separa en sus partes. Conviene saber cómo se llama cada una, porque los mensajes de error y la documentación dan por hecho el vocabulario:

  • Esquema: https, mailto, ftp. Todo lo anterior a los dos puntos, y lo que decide cómo se interpreta el resto.
  • Datos de usuario: un user:password opcional antes del host. Sigue siendo legal, y sigue siendo mala idea: viaja con cada petición y acaba en registros, en el historial del navegador y en cabeceras referrer.
  • Host: el nombre de dominio o la dirección IP. Todo lo que va después lo gestiona ese servidor, no la red.
  • Puerto: normalmente ausente, porque 443 para https y 80 para http están implícitos.
  • Origen: el esquema, el host y el puerto juntos. Es la unidad sobre la que se construye la seguridad del navegador: la política del mismo origen, CORS y el alcance de las cookies comparan orígenes, no rutas.
  • Ruta: la parte posterior al host y anterior a cualquier ? o #.
  • Consulta: los pares clave/valor tras el ?, separados por &.
  • Fragmento: todo lo que sigue al #. De forma única, esto nunca se envía al servidor; lo gestiona íntegramente el navegador.

El detalle del fragmento importa más de lo que parece. Como nunca sale del navegador, cualquier cosa que pongas tras un # es invisible para los registros del servidor, razón por la cual algunas aplicaciones de página única lo usaron históricamente para el enrutado, y por la que no es el sitio donde mirar al depurar una petición que nunca llegó.

Una última advertencia sobre lo que la codificación no hace. La codificación en porcentaje hace que el texto viaje con seguridad dentro de una URL; no es saneamiento ni un control de seguridad. Codificar un valor no lo hace seguro para interpolarlo en HTML, SQL o una orden de shell, y decodificar entradas no fiables puede revelar caracteres —separadores de ruta, bytes nulos— que la forma codificada ocultaba. Valida qué es un valor, aparte de codificar cómo viaja.

La dirección que escribes no siempre es la que se envía

Antes de que una URL vaya a ninguna parte se normaliza, y la reescritura es silenciosa. Esta herramienta muestra el resultado siempre que difiere de la entrada, porque esa cadena —y no la que escribiste— es la que llega al servidor y la que aparece en un registro:

HTTPS://Example.COM:443\a\b     escrito
https://example.com/a/b         enviado

Ahí se dispararon cuatro reglas distintas. El esquema y el host pasan a minúsculas, ya que ninguno distingue mayúsculas. El puerto desaparece porque 443 es el predeterminado de https. Las barras invertidas se convierten en barras normales, una regla de compatibilidad que sorprende a quien escribe rutas al estilo Windows. Y una ruta vacía se habría convertido en una sola barra. Nada de esto es un error, pero si comparas dos URL o cotejas una con una lista de permitidos, tienes que comparar las formas normalizadas o obtendrás una respuesta equivocada.

Un nombre de host con caracteres no ASCII también se reescribe, a una forma ASCII que empieza por xn--, llamada punycode. La herramienta muestra ambas direcciones: el nombre legible y el que realmente viaja. Conviene mirarlo en vez de saltárselo, porque dos nombres Unicode distintos pueden verse idénticos en pantalla —una «a» latina y una «а» cirílica son caracteres separados— y producir un punycode completamente distinto. Comparar las formas ASCII es la única manera fiable de distinguir un par así.

Una cosa nunca se normaliza: un parámetro de consulta repetido. Escribir ?tag=a&tag=b es del todo legal, y el estándar no dice qué significa, así que cada plataforma eligió su propia respuesta. PHP conserva el último valor, Express los reúne en un array, y muchos frameworks y URLSearchParams.get toman el primero. La herramienta marca las claves repetidas en lugar de listarlas dos veces sin comentario, porque el fallo resultante —un valor que funciona en un servicio y desaparece en otro— es genuinamente difícil de detectar leyendo.

Preguntas frecuentes

¿Cuál es la diferencia entre ámbito componente y URL completa?
El ámbito componente escapa también los delimitadores / ? : @ & = +, lo correcto para un valor suelto colocado dentro de una URL. El ámbito URL completa los deja intactos porque allí separan las partes de la dirección. Usar el ámbito componente sobre una URL entera convierte cada barra en %2F y produce una cadena inservible.
¿Por qué mi texto decodificado sigue teniendo un +?
Porque decodeURIComponent sigue el RFC 3986, donde + es simplemente un más. Los envíos de formulario y la mayoría de las cadenas de consulta usan codificación de formulario, donde + significa espacio. Activa «tratar + como espacio» cuando el texto venga de cualquiera de los dos.
¿Cómo codifico un más que es realmente un más?
Escríbelo como %2B. La mayoría de los analizadores leerán un + literal en una cadena de consulta como un espacio, así que cualquier más que forme parte de verdad de tus datos —en un número de teléfono, por ejemplo— tiene que escaparse.
¿Debo codificar la URL entera o solo las partes?
Solo las partes, y preferiblemente no a mano: construye la dirección con URL y URLSearchParams, que aplican la codificación correcta a cada componente. Codificar una URL ya ensamblada es de donde salen la mayoría de los errores de doble codificación.
¿Por qué el desglose muestra una URL distinta de la que pegué?
Porque esa es la que se envía. Una URL se normaliza antes de usarse: el esquema y el host pasan a minúsculas, se elimina un puerto por defecto, las barras invertidas se vuelven barras, una ruta vacía se vuelve una barra, y un host no ASCII se vuelve punycode. Si comparas URL o las cotejas con una lista de permitidos, compara estas formas normalizadas y no el texto en bruto.
¿Por qué no aparece desglose para example.com/path?
Porque no es una URL absoluta: no tiene esquema, así que no hay host que identificar. La herramienta no lo adivina por ti: example.com:8080 ya es una URL absoluta válida cuyo esquema es example.com y cuya ruta es 8080, de modo que anteponer https:// en silencio puede producir un desglose que parece razonable y es erróneo. Añade tú el esquema y aparecerán las partes.
¿Qué es la doble codificación?
Codificar un valor que ya estaba codificado, de modo que un %20 pasa a ser %2520: el propio signo de porcentaje se escapa. Suele manifestarse como secuencias %20 literales que aparecen en una página. Decodifica una vez y comprueba si sigues viendo escapes; si es así, se codificó dos veces.
¿Codificar un valor lo hace seguro?
No. La codificación en porcentaje trata del transporte, no de la seguridad. Un valor codificado sigue siendo lo que era, y necesita la misma validación y el mismo escapado adecuado al contexto antes de llegar a HTML, SQL o un shell.
¿Por qué el fragmento no se envía al servidor?
Por diseño: todo lo que va tras el # lo gestiona solo el navegador y nunca aparece en la petición. Por eso no puede verse en los registros del servidor, y por eso se usó históricamente para el enrutado del lado del cliente.
¿Se envía a algún sitio lo que pego?
No. La codificación, la decodificación y el desglose de la URL usan las funciones integradas del propio navegador y se ejecutan por completo en tu dispositivo. Nada de lo que pegues sale de él.