Explicación de la codificación de URL: codificación porcentual, encodeURI frente a encodeURIComponent y el error %2520
Todos los desarrolladores que han creado una URL con la entrada del usuario han encontrado esto: un término de búsqueda con un espacio o un símbolo rompe el enlace y, de repente, la mitad de la consulta falta en el servidor. La solución es la codificación de URL, también llamada codificación porcentual, pero viene con dos funciones que son fáciles de confundir y un error que produce el desconcertante %2520 en sus enlaces. Esta guía lo aclara todo.
Por qué las URL necesitan codificación
Las URL solo pueden contener un conjunto limitado de caracteres, definidos por un estándar llamado RFC 3986. Ese conjunto consiste básicamente en caracteres no reservados, letras, dígitos y algunos símbolos como guiones y guiones bajos, además de un puñado de caracteres reservados que tienen un significado estructural especial, como? para iniciar una consulta, & para separar parámetros, = para emparejar una clave con un valor, / para segmentos de ruta y # para un fragmento. Cualquier cosa fuera de ese conjunto, espacios, letras acentuadas, emoji o un símbolo reservado utilizado como datos en lugar de estructura, debe codificarse o la URL se romperá.
La codificación porcentual hace esto reemplazando un carácter no seguro con un signo de porcentaje seguido de su valor de byte hexadecimal de dos dígitos. Un espacio se convierte en %20. Un signo comercial se convierte en %26. Una arroba se convierte en %40. En el otro extremo, el servidor los decodifica a los caracteres originales. Todo el sistema existe para que texto arbitrario pueda viajar dentro de la estructura rígida de una URL sin ser confundido con parte de esa estructura.
El problema central: datos versus estructura
Esta es la situación que causa la mayoría de los errores. Imagine una búsqueda del texto literal "perros y gatos". Si coloca eso directamente en una cadena de consulta como q=cats & dogs, & se lee como separador de parámetros, el servidor ve un parámetro q=cats y un segundo parámetro sin sentido, dogs, y su búsqueda se interrumpe. El espacio también causa problemas. El signo comercial debe convertirse en %26 y el espacio en %20 para que el servidor entienda que son parte del valor, no de la estructura de la URL. La codificación es como se dice "este carácter son datos, no un delimitador".
encodeURI vs encodeURIComponent
JavaScript le ofrece dos funciones de codificación y elegir la incorrecta es uno de los errores de URL más comunes. La diferencia es lo que consideran "seguro" y lo dejan en paz.
encodeURIComponent codifica todo lo reservado, incluido /? & = # y más. Está destinado a codificar un valor único que está insertando en una URL, un valor de parámetro de consulta, un término de búsqueda, un destino de redireccionamiento. Úselo para las piezas. encodeURI, por el contrario, deja deliberadamente los caracteres de la estructura de la URL (/? & =), porque está destinado a codificar una URL completa, ya ensamblada, mientras la mantiene funcional. Úselo para todo, rara vez.
La regla general: si está codificando un valor que va dentro de una URL, use encodeURIComponent. Si está codificando una URL completa y solo desea corregir caracteres ilegales perdidos sin romper su estructura, use encodeURI. En caso de duda, casi siempre querrás encodeURIComponent, porque casi siempre estás codificando un valor.
El error %2520: doble codificación
Este confunde a todos la primera vez. Ves %2520 en una URL donde esperabas %20 y el enlace está roto. Esto es lo que sucedió: una cadena que ya estaba codificada se codificó por segunda vez. La primera codificación convirtió un espacio en %20. La segunda codificación luego codificó el signo de porcentaje en sí, % se convierte en %25, convirtiendo %20 en %2520. Ahora el servidor lo decodifica una vez a %20 (literalmente, el texto "%20") en lugar de un espacio, y todo lo que ocurre en sentido descendente está mal.
La causa casi siempre es codificar un valor que ya estaba codificado, por ejemplo, crear una URL a partir de una cadena que ya estaba codificada como URL y luego ejecutarla nuevamente a través del codificador. La regla para evitarlo: codificar únicamente texto sin formato y sin codificar. Nunca codifique una URL o un valor que ya esté codificado. Si no está seguro de si una cadena ya está codificada, decodifíquela primero y luego codifíquela exactamente una vez.
La ambigüedad del signo más
Una trampa más. En una cadena de consulta, un signo más (+) a veces se interpreta como un espacio, un legado de la codificación de formulario HTML más antigua, application/x-www-form-urlencoded. Pero en una ruta URL, + es una ventaja literal. Esta inconsistencia significa que un + en sus datos puede leerse como un espacio en un lugar y un más en otro. Lo más seguro es codificar siempre un espacio como %20, que es inequívoco en todas partes, en lugar de depender de +. Si ve que los espacios se convierten en ventajas o viceversa, esta ambigüedad suele ser la culpable.
La conclusión práctica
Codifique los valores que ingresa en las URL, use encodeURIComponent para esos valores, codifique solo texto sin formato para evitar el error de doble codificación %2520 y prefiera %20 sobre + para los espacios. Cuando necesita crear o inspeccionar una URL a mano, un codificador y decodificador rápido le permite ver exactamente en qué se convierte una cadena y detectar estos problemas antes de enviarse.