Español

Herramientas de desarrollo · Codificador y decodificador de URL

¿Por qué + se convierte en un espacio cuando se decodifica una cadena de consulta y cuando no?

· Cómo funciona

codificación de URL javascript flujo de trabajo del desarrollador

Un signo más y su forma codificada en porcentaje permanecen distintos a través de diferentes decodificadores
Ilustración de vector original de ToolAcre

Si + significa espacio depende del decodificador al que llame. Esta publicación explica cómo decodeURIComponent, URLSearchParams y los marcos de servidor tratan cada uno +, y cómo evitar convertir una ventaja real en un espacio.

¿Por qué + se convierte en un espacio cuando se decodifica una cadena de consulta y cuando no?

Los envíos de formularios HTML utilizan el formato application/x-www-form-urlencoded, donde el espacio se convierte en más. Un servidor que recibe nombre=Alice+Smith reemplaza cada signo más con espacio antes de extraer el valor. Cuando un plus real pertenece a los datos, como en un cálculo 5+3, llega al servidor como 5 3 después del paso de decodificación del formulario. Esta conversión invisible es la raíz de la confusión.

La decodificación de JavaScript produce diferentes resultados según la función que utilice. URLSearchParams trata a plus como espacio, coincidiendo con el comportamiento del servidor. Pero decodeURIComponent deja plus intacto, tratándolo literalmente. Esta asimetría entre funciones es la razón por la que la misma entrada se decodifica de manera diferente. Un desarrollador que espera que ambos decodificadores produzcan el mismo resultado descubre que no es así.

Dos codificaciones que se parecen: RFC 3986 codificación porcentual versus aplicación/x-www-form-urlencoded

Dos estándares de codificación parecen similares pero funcionan de manera diferente. RFC 3986 define la codificación porcentual: cualquier carácter se convierte en %HH. El espacio se convierte en %20. El estándar application/x-www-form-urlencoded agrega una abreviatura: el espacio puede ser más. Cualquiera de los dos funciona en el contexto del formulario, pero plus es opcional y específico de ese estándar. Son dominios diferentes con apariencia similar.

Llamar a decodeURIComponent aplica solo la decodificación RFC 3986. Lee %20 como espacio y más como literal más. URLSearchParams aplica reglas de decodificación de formularios: los escapes porcentuales se convierten en sus caracteres y el signo más se convierte en espacio. Las dos funciones resuelven el mismo problema en diferentes dominios. Mezclarlos hace que un plus real desaparezca o que un espacio se convierta en plus y no se convierta.

decodeURIComponent deja + solo; URLSearchParams lo convierte en un espacio: se comparan los dos comportamientos de JavaScript

El comportamiento del servidor varía, lo que agrava el problema. Rails o Django aplican automáticamente la regla de forma: más se convierte en espacio. Pero extraer y decodificar manualmente la cadena de consulta sin formato con un decodificador de URL deja plus intacto. El mismo valor procesado por diferentes marcos produce resultados diferentes. El código del servidor a menudo maneja esto implícitamente, ocultando el problema hasta que escribes un descodificador personalizado.

Ejemplo: un campo de número de teléfono almacena +1-555-0100 con un signo más como código de país. Un formulario HTML lo codifica como %2B1-555-0100 porque JavaScript codifica más como %2B. El servidor recibe esto. Si se aplica la decodificación de formularios, %2B se convierte en más y el valor es correcto. Si un proxy elimina la codificación, llamar a decodeURIComponent en el resultado produce +1-555-0100. Cada capa se decodifica una vez.

Qué hacen los servidores: comportamiento del marco común en la cadena de consulta y el cuerpo de la solicitud, descrito en términos generales

JavaScript puede codificar valores usando encodeURIComponent. Dado a+b, se produce a%2Bb. Cuando esa cadena codificada llega a un servidor o decodificador con reconocimiento de formulario, %2B decodifica como plus y el resultado es correcto. Si codifica usando la regla de formulario, un espacio se convierte en más y un más real se convierte en %2B. De cualquier manera, la codificación produce%2Bb. La interpretación depende de qué regla de decodificación se aplique.

Pruebe el viaje de ida y vuelta: comience con a+b. Codifique con encodeURIComponent para obtener un%2Bb. Decodifica a%2Bb con decodeURIComponent y recupera a+b. Pase a+b a URLSearchParams: trata a plus como un espacio, lo que produce una b. Pase a%2Bb a URLSearchParams para recuperar a+b. La misma entrada decodificada de dos maneras produce diferentes salidas dependiendo del decodificador que utilice.

Ejemplo resuelto: 'a+b' y 'a%2Bb' a través de ambos decodificadores: cuatro resultados en una tabla

Los errores comunes siguen directamente. Un desarrollador decodifica con decodeURIComponent y se pregunta por qué los datos entrantes del formulario con una ventaja real se rompen. Deberían haber usado URLSearchParams. Por el contrario, alguien usa URLSearchParams cuando debería usar decodeURIComponent, y cada literal más desaparece. La codificación dos veces produce %252B, lo que requiere que coincidan los pares codificador-decodificador para decodificar correctamente.

Otro error es construir una cadena de consulta a mano como ?q=valor sin codificación. Cualquier signo comercial o igual en el valor crea silenciosamente un nuevo parámetro. El navegador no duda en la concatenación; trata el resultado como si estuviera formado correctamente. Sólo la codificación intencional con encodeURIComponent evita esto. El codificador y decodificador de URL muestra las tres funciones y revela lo que produce cada una.

Errores comunes: decodificar dos veces o codificar un espacio como + en un segmento de ruta

La regla de codificación de formulario se llama aplicación/x-www-form-urlencoded porque describe el encabezado de tipo de contenido del cuerpo de la solicitud HTTP. Los formularios HTML sin carga de archivos envían el cuerpo en este formato. Las cadenas de consulta en las URL también utilizan esta convención, aunque técnicamente no tienen un estándar de codificación oficial. Las especificaciones de URL tratan la consulta como opaca; Además, el significado no es obligatorio. Pero en las aplicaciones web, más suele significar espacio.

Para garantizar un comportamiento correcto, codifique deliberadamente y decodifique con la función de coincidencia. Si codificó con encodeURIComponent, decodifique con decodeURIComponent. Si lee datos de formulario HTML o cuerpos de solicitud en formato de formulario, utilice URLSearchParams. Nunca adivines basándote en la apariencia. Una cadena como a+b es ambigua. Los decodificadores no son intercambiables.

Lo que esto no cubre: datos de formularios de varias partes y JSON cuerpos de solicitud

Los datos de formularios de varias partes, los JSON cuerpos de solicitud y otros estándares tienen reglas de codificación independientes. JSON no usa más para espacio o codificación porcentual; utiliza escapes Unicode. Multipart utiliza límites diferentes. Este artículo cubre cadenas de consulta y cuerpos codificados en formato únicamente, porque ahí es donde aparece la ambigüedad del plus. Siempre revisa el encabezado Content-Type y el RFC que lo define.

Codifique siempre un plus literal como %2B cuando pertenezca a un valor de consulta. El codificador y decodificador de URL muestra cómo plus está protegido como %2B en modo componente, separado de los espacios que se convierten en %20. Pase a+by a%2Bb por cada modo y luego examine los resultados. Esa comparación muestra por qué la misma entrada se decodifica de manera diferente. La diferencia es el comportamiento correcto de dos estándares diferentes.

Conclusión: codifique siempre un plus literal como %2B: cómo el codificador y descodificador de URL muestra cómo se ve un valor como valor de consulta codificado por porcentaje

Conclusión: plus en una cadena de consulta es la forma abreviada de codificación de espacio, no un plus literal, a menos que provenga de una codificación que lo protegía como %2B. Un decodificador incorrecto pierde esa protección. URLSearchParams es más seguro en JavaScript moderno; maneja la codificación de formularios y otorga acceso a parámetros con nombre. Para cadenas sin formato, encodeURIComponent protege todo; decodeURIComponent interpreta %20 y porcentajes pero trata más literalmente.

Pruebe esto: cree ?x=a+b a mano y péguelo en el codificador y decodificador de URL. Inspeccione y observe cómo URLSearchParams lo divide en el parámetro x con valor a b. Pegue ?x=a%2Bb y vea el valor a+b. Utilice encodeURIComponent para crear la URL y compararla. Esa confirmación visual aclara la regla: las reglas de formulario usan más, la codificación porcentual usa %20, mezclarlas es la razón por la cual más desaparece en el espacio.