2010-02-24 9 views
41

Esta pregunta se refiere a los caracteres en la porción de cadena de consulta de la URL, que aparecen después del carácter de marca ?.¿Qué caracteres se deben escapar en una cadena de consulta HTTP?

Por Wikipedia, ciertos caracteres se dejan como están y otros se codifican (generalmente con una secuencia de escape %).

He estado tratando de rastrear esto hasta las especificaciones reales, por lo que entiendo la justificación detrás de cada viñeta en esa página de Wikipedia.

contradicción Ejemplo 1:

El HTML specification dice al espacio codificar como + y aplaza el resto a RFC1738. Sin embargo, este RFC dice que ~ no es seguro y además que "[a] ll caracteres inseguros siempre deben estar codificados dentro de la URL". Esto parece contradecir Wikipedia.

En la práctica, IE8 codifica ~ en las cadenas de consulta que genera, mientras que FF3 lo deja como está.

contradicción Ejemplo 2:

Wikipedia afirma que todos los caracteres que no se mencionan deben ser codificados. ! no se menciona en Wikipedia. Pero RFC1738 indica que ! es un carácter "especial" y "puede usarse sin codificar". Esto parece contradecir Wikipedia que dice que debe estar codificado.

En la práctica, IE8 codifica ! en las cadenas de consulta que genera, mientras que FF3 lo deja como está.

Entiendo que la moraleja de esto probablemente sea codificar aquellos caracteres que están en duda entre Wikipedia y las especificaciones. Quizás incluso yendo tan lejos como para codificar todo lo que no es [A-Za-z0-9]. Me gustaría saber los estándares reales sobre esto.

Conclusiones

el algoritmo descrito en Wikipedia codifica precisamente aquellos caracteres que no son RFC3986 unreserved characters. Es decir, codifica todos los caracteres que no sean alfanuméricos y -._~. Como caso especial, el espacio se codifica como + en lugar de %20 por RFC3986.

Algunas aplicaciones utilizan un RFC anterior. Para la comparación, el RFC2396 unreserved characters son alfanuméricos y !'()*-._~.

Para comparar, el HTML5 working draft algorithm codifica todos los caracteres que no sean alfanuméricos y *-._. La codificación de caso especial para espacio sigue siendo +. Las diferencias notables son que * no está codificado y ~ está codificado. (Técnicamente, este manejo de * es compatible con RFC3986 a pesar de que está en *reserved porque está en la sub-delims que se permite en la producción query.)

+2

Wikipedia no es un organismo de normas. Si tiene dudas, use el estándar. –

+8

@John, aunque es importante usar el estándar * correcto *. Que es 3986 en este caso, no el antiguo 1738. –

Respuesta

37

La respuesta se encuentra en el documento RFC 3986, específicamente Section 3.4.

El componente de consulta se indica con el primer signo de interrogación ("?") Carácter y termina con un signo de número ("#") carácter o al final de la URI.

...

Los caracteres de barra ("/") y el signo de interrogación ("?") Pueden representar datos dentro del componente de consulta.

Técnicamente, RFC 3976 a 3,4 define el componente de consulta como:

query  = *(pchar/"/"/"?") 

Esta sintaxis significa que consulta puede incluir todos los caracteres de pchar así como / y ?. pchar se refiere a otra especificación de caracteres de ruta. Amablemente, Appendix A de RFC 3986 enumera las definiciones ABNF pertinentes, sobre todo:

query   = *(pchar/"/"/"?") 
pchar   = unreserved/pct-encoded/sub-delims/":"/"@" 
unreserved = ALPHA/DIGIT/"-"/"."/"_"/"~" 
pct-encoded = "%" HEXDIG HEXDIG 
sub-delims = "!"/"$"/"&"/"'"/"("/")"/"*"/"+"/","/";"/"=" 

Por lo tanto, además de todos caracteres alfanuméricos y ciento codificada caracteres, una consulta puede legalmente incluir los siguientes caracteres no codificados:

/ ? : @ - . _ ~ ! $ & ' () * + , ; = 

Por supuesto, es posible que desee tener en cuenta que '=' y '&' suelen tener un significado especial dentro de una consulta.

+2

Nota: además de '=' y '&', el servidor podría restringir otros caracteres de cadena de consulta legalmente no codificados como '.' (dot) en PHP donde será reemplazado por' _' (guión bajo) en '$ _GET' y' $ _POST'. Ver: http://stackoverflow.com/questions/68651/get-php-to-stop-replacing-characters-in-get-or-post-arrays (también tiene una solución alternativa). – GitaarLAB

Cuestiones relacionadas