Por qué en las direcciones aparecen %20 y %C3%B1

Una URL solo puede contener un conjunto pequeño de caracteres: letras, cifras y pocos símbolos. Todo lo demás, espacios, letras acentuadas, la ñ, los emoji, se convierte primero en bytes UTF-8 y luego cada byte se escribe como % seguido de dos cifras hexadecimales. El espacio se vuelve %20 y la ñ %C3%B1.

Algunos caracteres tienen un significado estructural: / separa los tramos de la ruta, ? abre la query string, & separa los parámetros, = separa nombre y valor, # introduce el fragmento. Si aparecen dentro de un valor hay que codificarlos, o rompen la dirección. Esa es la diferencia entre encodeURIComponent, que los codifica, y encodeURI, que los deja porque trabaja sobre una URL entera.

En los formularios web y en las query strings el espacio también se escribe a menudo como +. Por eso la decodificación aquí convierte el + en espacio, como hacen los servidores; en una ruta, en cambio, el + sigue siendo un +.

Errores frecuentes

  • Usar encodeURI para el valor de un parámetro: un & en el valor parte el parámetro en dos.
  • Codificar dos veces: %20 se convierte en %2520 y el servidor recibe el texto literal %20.
  • Construir una URL concatenando cadenas sin codificar: además de errores, abre la puerta a la inyección de parámetros.

Preguntas frecuentes

¿Qué diferencia hay entre encodeURI y encodeURIComponent?

encodeURIComponent codifica todo salvo letras, cifras y - _ . ! ~ * ' ( ): sirve para un solo valor. encodeURI también deja : / ? # [ ] @ & = + $ , ;: sirve para una dirección ya compuesta.

¿Por qué el espacio a veces es %20 y a veces +?

%20 es la codificación general del espacio en una URL. El + viene de los formularios HTML (application/x-www-form-urlencoded) y solo vale como espacio en la query string.

¿Qué es Punycode?

Es la forma en que los dominios con caracteres no ASCII, como españa.es, se escriben en el DNS: xn--espaa-rta.es. El navegador muestra la forma legible, pero por debajo usa la codificada.

Cómo funciona este cálculo

Codificación: el texto se convierte en bytes UTF-8 y cada byte fuera del conjunto permitido se vuelve %HH, siendo HH su valor hexadecimal. encodeURIComponent solo permite A–Z a–z 0–9 - _ . ! ~ * ' ( ); encodeURI permite además ; , / ? : @ & = + $ #. Decodificación: cada %HH vuelve a su byte, los bytes se leen como UTF-8 y el + pasa a ser un espacio.