Codificador y Decodificador de URL

Componente también escapa / ? & = — úsalo para un solo valor de consulta. URL completa los conserva, así la URL sigue siendo válida.

Nada de lo que escribes aquí se almacena, registra ni comparte.

Codifica texto para usarlo en una URL, o decodifícalo de vuelta. Elige si estás codificando un solo valor de consulta o una URL completa, porque cada caso necesita un escapado distinto.

Cómo usarlo

  1. Elige codificar o decodificar.
  2. Al codificar, elige Componente para un solo valor o URL completa para una dirección entera.
  3. Pega tu texto y copia el resultado.

Por qué hay dos modos

La RFC 3986 divide los caracteres que pueden aparecer en una URL en dos grupos. Los no reservados - las letras, los dígitos y los cuatro signos - _ . ~ - siempre se representan a sí mismos y nunca se codifican. Los reservados tienen un significado estructural: los dos puntos tras el esquema, las barras entre segmentos de la ruta, el signo de interrogación que abre la consulta, el & y el = que separan parámetros y la almohadilla que inicia el fragmento.

Los dos modos solo se diferencian en lo que hacen con ese segundo grupo. El modo componente también escapa los reservados, que es lo que quieres cuando el texto va dentro de un único hueco - un valor de consulta, un segmento de ruta - y no debe interpretarse como estructura. El modo URL completa los deja como están, de modo que una dirección entera se conserva con su esquema, sus barras y sus separadores funcionando.

Usar el modo equivocado suele notarse enseguida. Pasa una dirección completa por el modo componente y https://example.com se convierte en https%3A%2F%2Fexample.com, que ya no se resuelve. Pasa un único valor por el modo URL completa y un & perdido en él dividirá tu parámetro en dos sin avisar.

Los caracteres que dan problemas

El espacio es el primero con el que uno se topa. En una ruta o una consulta se convierte en %20. En el envío de un formulario HTML se convierte en +, porque así lo establecen las antiguas reglas de application/x-www-form-urlencoded, y ambas convenciones siguen usándose a diario. Por eso existe la opción de tratar + como espacio al decodificar: actívala para la query string de un formulario y déjala desactivada para una ruta, donde + es un signo más literal y convertirlo en espacio corrompe el valor.

El & y el = deben escaparse dentro de un valor o el servidor partirá la consulta por el sitio equivocado; el caso clásico es un término de búsqueda o un bloque Base64 que casualmente contiene uno. La almohadilla ni siquiera llega al servidor: todo lo que va detrás es el fragmento, que gestiona el navegador, así que un # sin escapar dentro de un parámetro trunca la petición sin avisar.

La barra dentro de un valor merece especial cuidado. Codificada como %2F es válida, pero bastantes servidores y proxies la decodifican antes de enrutar, así que aun así puede interpretarse como separador de ruta. Si un valor puede contener barras, ponerlo en la consulta en lugar de en la ruta evita el problema por completo.

Doble codificación

La codificación porcentual no es idempotente. El propio signo de porcentaje es un carácter que hay que codificar, así que se convierte en %25, y codificar una cadena ya codificada transforma %20 en %2520. Esa secuencia es la huella visible de una URL que ha pasado por un paso de codificación de más, y en cuanto la reconoces una vez, la ves en todas partes.

Ocurre cuando el código de la aplicación codifica un valor y luego un framework, un cliente HTTP o una plantilla que suponía recibir texto sin procesar lo vuelve a codificar. La solución es eliminar uno de los dos pasos, no decodificar dos veces en el lado receptor, lo que solo cambia el error de sitio. Decodificar aquí una vez por capa, y observar si %2520 pasa a %20 y luego a un espacio, te dice cuántas capas había realmente.

Caracteres no ASCII y lo que la codificación porcentual no cubre

El texto se convierte primero a UTF-8 y después se codifica cada byte, así que un solo carácter japonés se convierte en tres secuencias de escape en lugar de una. Es lo que exige el estándar de URL, y por eso el japonés, el chino, el coreano, las letras con tilde y los emoji hacen el viaje de ida y vuelta sin problemas aquí.

Los nombres de dominio son la excepción, y la diferencia importa. La parte del host de una URL no se codifica con porcentajes: un dominio internacionalizado se convierte con Punycode, lo que produce un nombre que empieza por xn--. Codificar con porcentajes un nombre de host produce algo que parece codificado y no se resuelve en ningún sitio. Esta herramienta solo se ocupa de la ruta, la consulta y el fragmento.

La anatomía de una URL

Una URL tiene más partes de las que la mayoría de la gente usa: esquema, una sección userinfo opcional, host, puerto opcional, ruta, query y fragmento. Escrita completa, https://user:[email protected]:8443/a/b?x=1#top contiene todas. La forma userinfo está obsoleta para HTTP y los navegadores la eliminan o advierten sobre ella, precisamente porque se usaba para hacer que un host hostil pareciera uno conocido.

Cada pieza tiene reglas distintas. El host no distingue mayúsculas de minúsculas y no puede contener percent-encoding; la ruta sí las distingue en la mayoría de los servidores; la query no tiene más gramática estándar que ser una cadena, y los pares key=value separados por ampersands son una convención y no una especificación; y el fragmento nunca sale del navegador.

La resolución de referencias relativas es la parte que sorprende a la gente. Un enlace a b/c desde /a/page se resuelve como /a/b/c, pero desde /a/page se resuelve como /a/page/b/c: la barra final cambia la base. Por eso una barra final que falta o que sobra rompe todos los recursos relativos de una página, y por eso vale la pena configurar una vez una redirección canónica entre ambas formas.

Las query strings tienen convenciones, no reglas

No existe un estándar para expresar un arreglo en una query string, y por eso cada framework lo hace distinto: tags=a&tags=b repite la clave, tags[]=a&tags[]=b agrega corchetes y tags=a,b usa un delimitador. Las tres son URLs válidas y cada una se interpreta de una forma diferente según la biblioteca que esté del otro lado.

Lo mismo aplica a las estructuras anidadas, los booleanos y los valores vacíos. ¿flag= significa false, cadena vacía o presente pero sin valor? La respuesta es lo que decida el parser que recibe, así que una API a la que esto le importe debería documentarlo y validar en lugar de suponer.

En JavaScript, URLSearchParams maneja correctamente la codificación y las claves repetidas, y conviene preferirlo antes que armar cadenas a mano. Ten en cuenta que codifica los espacios como signos de más, siguiendo la convención de los formularios, mientras que encodeURIComponent produce %20: ambos se decodifican como espacio en una query string, y solo uno de ellos lo hace en una ruta.

Los problemas de seguridad que viven en el manejo de URLs

Un open redirect es un endpoint que envía al visitante a una URL entregada en un parámetro sin verificarla. Se usa para que un enlace de phishing empiece en un dominio en el que la víctima confía, y sigue siendo un hallazgo habitual en las revisiones de seguridad. La solución es una lista de destinos permitidos, o aceptar únicamente rutas en lugar de URLs absolutas.

El server-side request forgery es la misma clase de problema apuntando hacia adentro: el servidor descarga una URL que entregó un usuario, y el usuario entrega una dirección interna, un endpoint de metadatos de la nube o una redirección hacia uno de ellos. Aquí se han explotado una y otra vez las diferencias de parsing entre bibliotecas, ya que dos parsers pueden discrepar sobre a qué host apunta una URL manipulada.

Los ataques de homógrafos aprovechan los nombres de dominio internacionalizados, donde caracteres cirílicos y latinos que se ven idénticos producen hosts distintos. Los navegadores se defienden mostrando la forma punycode cuando un nombre mezcla sistemas de escritura, y por eso un enlace sospechoso a veces aparece con xn-- en la barra de direcciones. Vale la pena reconocer ese prefijo.

URLs canónicas, duplicados y parámetros de seguimiento

La misma página suele ser accesible en varias direcciones: con y sin www, con y sin barra final, por http y por https, con un sufijo index.html y con cualquier cantidad de parámetros de seguimiento añadidos. Para un buscador eso puede parecer páginas distintas que comparten el mismo contenido, lo que divide la autoridad que la página se ha ganado.

Dos mecanismos lo resuelven. Una redirección 301 se encarga de las variantes estructurales: elige una forma y manda todo lo demás hacia ella. Un elemento link canonical en el head indica la dirección preferida para las variantes que no puedes redirigir, que son principalmente los casos con parámetros.

Los parámetros de seguimiento merecen una nota aparte: utm_source y compañía los agrega el sistema de origen y producen una URL distinta para cada campaña. Su lugar está en la analítica, no en la URL canónica, y quitarlos del lado del cliente una vez registrados mantiene limpios los enlaces que se comparten. Lo mismo vale para los parámetros fbclid y gclid que algunas plataformas añaden automáticamente.

Diseñar rutas que envejezcan bien

Una URL es una promesa, porque otras personas enlazan a ella y tú no controlas esos enlaces. Eso es un argumento a favor de rutas que describan el recurso y no la implementación: /guides/subnetting en lugar de /page.php?id=4718, y sin extensiones de archivo que aten la dirección a la tecnología que la sirve.

Mantenlas en minúsculas y con guiones. Que el servidor distinga mayúsculas significa que /About y /about pueden ser páginas diferentes, cosa que nunca es intencional, y el guion es el separador de palabras habitual en un slug. Evita las fechas en las rutas salvo que el contenido sea realmente un archivo histórico, ya que /2024/pricing se ve desactualizado un año después aunque el contenido esté vigente.

Cuando una URL tenga que cambiar, redirige la antigua de forma permanente y conserva esa redirección indefinidamente. Romper enlaces es la única decisión de esta lista que no se puede deshacer desde tu lado, porque los enlaces que más importan son los que están en sitios de los que nunca has oído hablar.

Preguntas frecuentes

¿Cuál es la diferencia entre Componente y URL completa?
Componente usa encodeURIComponent y escapa también los caracteres reservados / ? & = :, que es lo correcto para un valor de consulta o un segmento de ruta. URL completa usa encodeURI y los deja intactos para que la dirección siga siendo válida. Codificar una URL entera en modo Componente convierte https:// en https%3A%2F%2F y la rompe.
¿Cuál debo usar para un parámetro de consulta?
Componente. Un valor que contenga & o = tiene que escaparse; si no, el servidor lo interpreta como separador y parte tu parámetro en el sitio equivocado.
¿Por qué falla la decodificación con un escape mal formado?
Un signo de porcentaje debe ir seguido de exactamente dos dígitos hexadecimales. Un % suelto (como en "100%") o una secuencia truncada como %E4%B8 no es válida, así que la decodificación se detiene en lugar de adivinar.
¿Cuándo necesito la opción de + como espacio?
Los envíos de formulario codifican un espacio como + en lugar de %20. Actívala al decodificar una cadena de consulta procedente de un formulario HTML. Déjala desactivada para segmentos de ruta, donde + es un signo más literal.
¿Funciona con tildes y otros idiomas?
Sí. El texto se convierte a UTF-8 antes de la codificación porcentual, así que el español con tildes, el japonés, el chino, el coreano y los emoji vuelven intactos.

Última actualización:

Informar de un problema

Incluye los pasos, el resultado esperado y el real. Elimina secretos y datos personales.

Herramientas relacionadas