URL que codifica el carácter de espacio: + o% 20?


Respuestas:


425

De Wikipedia (énfasis y enlace agregado):

Cuando se envían datos ingresados ​​en formularios HTML, los nombres y valores de los campos de formulario se codifican y se envían al servidor en un mensaje de solicitud HTTP utilizando el método GET o POST, o, históricamente, por correo electrónico. La codificación utilizada por defecto se basa en una versión muy temprana de las reglas generales de codificación porcentual de URI, con una serie de modificaciones , como la normalización de nueva línea y la sustitución de espacios con "+" en lugar de "% 20". El tipo de datos MIME codificados de esta manera es application / x-www-form-urlencoded, y actualmente está definido (todavía de una manera muy desactualizada) en las especificaciones HTML y XForms.

Por lo tanto, el porcentaje de codificación real se usa %20mientras que los datos de formulario en URL están en una forma modificada que usa +. Por lo tanto, es más probable que solo vea +en las URL en la cadena de consulta después de un ?.


2
Entonces, la codificación + técnicamente sería una codificación de datos multiparte / formulario, mientras que la codificación porcentual es application / x-www-form-urlencoded?
BC.

17
@BC: no: multipart/form-datautiliza la codificación MIME; application/x-www-form-urlencodedusos +y URI codificados adecuadamente %20.
McDowell

8
"¿Entonces es más probable que solo vea + en las URL en la cadena de consulta después de un?" Es un eufemismo. Nunca debería ver "+" en la parte de la ruta de la URL porque no hará lo que espera (espacio).
Adam Gent

34
Básicamente: el objetivo de la presentación GET es http://www.bing.com/search?q=hello+worldun recurso con espacio en el nombrehttp://camera.phor.net/cameralife/folders/2012/2012-06%20Pool%20party/
William Entriken

8
Tenga en cuenta que para los enlaces de correo electrónico, necesita% 20 y no + después de?. Por ejemplo, mailto:support@example.org?subject=I%20need%20help. Si lo intentó con +, el correo electrónico se abrirá con + es en lugar de espacios.
Sygmoral

288

Esta confusión se debe a que las URL todavía están "rotas" hasta el día de hoy.

Tome " http://www.google.com " por ejemplo. Esta es una URL. Una URL es un Localizador uniforme de recursos y es realmente un puntero a una página web (en la mayoría de los casos). Las URL en realidad tienen una estructura muy bien definida desde la primera especificación en 1994.

Podemos extraer información detallada sobre la URL " http://www.google.com ":

+---------------+-------------------+
|      Part     |      Data         |
+---------------+-------------------+
|  Scheme       | http              |
|  Host         | www.google.com    |
+---------------+-------------------+

Si miramos una URL más compleja como:

" https: // bob: bobby@www.lunatech.com: 8080 / file; p = 1? q = 2 # third "

podemos extraer la siguiente información:

+-------------------+---------------------+
|        Part       |       Data          |
+-------------------+---------------------+
|  Scheme           | https               |
|  User             | bob                 |
|  Password         | bobby               |
|  Host             | www.lunatech.com    |
|  Port             | 8080                |
|  Path             | /file;p=1           |
|  Path parameter   | p=1                 |
|  Query            | q=2                 |
|  Fragment         | third               |
+-------------------+---------------------+

https://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third
\___/   \_/ \___/ \______________/ \__/\_______/ \_/ \___/
  |      |    |          |          |      | \_/  |    |
Scheme User Password    Host       Port  Path |   | Fragment
        \_____________________________/       | Query
                       |               Path parameter
                   Authority

Los caracteres reservados son diferentes para cada parte.

Para las URL HTTP, un espacio en una parte del fragmento de ruta debe codificarse a "% 20" (no, absolutamente no "+"), mientras que el carácter "+" en la parte del fragmento de ruta puede dejarse sin codificar.

Ahora en la parte de consulta, los espacios pueden codificarse en "+" (para compatibilidad con versiones anteriores: no intente buscarlo en el estándar URI) o "% 20" mientras que el carácter "+" (como resultado de esta ambigüedad ) debe escaparse a "% 2B".

Esto significa que la cadena "azul + azul claro" debe codificarse de manera diferente en la ruta y las partes de consulta:

" http://example.com/blue+light%20blue?blue%2Blight+blue ".

A partir de ahí, puede deducir que la codificación de una URL completamente construida es imposible sin un conocimiento sintáctico de la estructura de la URL.

Esto se reduce a:

Deberías tener %20antes ?y +después.

Fuente


>> debería tener% 20 antes del? y + después Perdón por la tonta pregunta. Sé de alguna manera que el parámetro hashtag se usa después de "?" parámetro de signo de interrogación Aunque de alguna manera es diferente porque usar "#" no recarga la página. Pero he estado tratando de usar el signo% 20 y + después del hashtag "#", y parece que no funciona. ¿Cuál debe usarse después de "#"?
Philcyb

@Philcyb Quizás quieras leer esto en.wikipedia.org/wiki/Percent-encoding
Matas Vaitkevicius

¿La parte de consulta tiene realmente un estándar "oficial"? Básicamente pensé que esa parte es específica de la aplicación. El 99.99% de las aplicaciones usan key1=value1&key1=value2donde las claves y los valores están codificados con las reglas que encodeURIComponentsiguen, pero AFAIK el contenido de la parte de la consulta es totalmente 100% hasta la aplicación. Aparte de eso, solo va al primero, #no hay codificación oficial.
gman

¡Una respuesta duplicada para la pregunta duplicada! Pero hmm, ok, me di por vencido en ambos.
Vladimir Vukanac

3
Ese etiquetado de componentes ASCII es épico.
jsejcksn

25

Yo recomendaría %20.

¿Los estás codificando?

Sin embargo, esto no es muy consistente en todos los idiomas. Si no me equivoco, en PHP urlencode()trata los espacios como +mientras que Python los urlencode()trata como %20.

EDITAR:

Parece que estoy equivocado. Python urlencode()(al menos en 2.7.2) usa en quote_plus()lugar de quote()y por lo tanto codifica espacios como "+". Parece también que la recomendación del W3C es el "+" según aquí: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1

Y de hecho, puede seguir este interesante debate sobre el rastreador de problemas de Python sobre qué usar para codificar espacios: http://bugs.python.org/issue13866 .

EDITAR # 2:

Entiendo que la forma más común de codificar "" es como "+", pero solo una nota, puede ser solo yo, pero esto me parece un poco confuso:

import urllib
print(urllib.urlencode({' ' : '+ '})

>>> '+=%2B+'

No está codificado. Tratando de determinar desde una perspectiva estética cómo serán mis urls que contienen espacios.
BC.

Hola, también estoy confundido. Cuando el usuario envía el formulario html, ¿cómo codifica el formulario el espacio? con que personaje ¿El resultado depende del navegador?
GMsoF

1
Y el URLEncoder.encode()método en Java también lo convierte +.
Febrero

Y luego surge la pregunta de cómo tratar la codificación en el cuerpo de una solicitud POST: "Content-Type: application / x-www-form-urlencoded" donde los parámetros tienen la forma de "a = b & c = d", pero no están en una URL, solo el cuerpo del "documento". Hicieron un verdadero desastre con este problema, y ​​es muy difícil encontrar respuestas definitivas.
fyngyrz

Perls uri_escape () los trata como% 20
someuser

16

Un espacio solo puede codificarse a "+" en la consulta "pares de clave-valor de tipo de contenido" application / x-www-form-urlencoded "parte de una URL. En mi opinión, esto es un MAYO, NO DEBE. En el resto de las URL, se codifica como% 20.

En mi opinión, es mejor codificar siempre los espacios como% 20, no como "+", incluso en la parte de consulta de una URL, porque es la especificación HTML (RFC-1866) la que especifica que los caracteres de espacio deben codificarse como " + "in" application / x-www-form-urlencoded "pares de clave-valor de tipo de contenido (ver párrafo 8.2.1. subpárrafo 1.)

Esta forma de codificar datos de formulario también se proporciona en especificaciones HTML posteriores. Por ejemplo, busque párrafos relevantes sobre application / x-www-form-urlencoded en la especificación HTML 4.01, y así sucesivamente.

Aquí hay una cadena de muestra en URL donde la especificación HTML permite codificar espacios como ventajas: " http://example.com/over/there?name=foo+bar ". Entonces, solo después de "?", Los espacios se pueden reemplazar por más . En otros casos, los espacios deben codificarse en% 20. Pero como es difícil determinar correctamente el contexto, es la mejor práctica nunca codificar espacios como "+".

Recomendaría codificar en porcentaje todos los caracteres excepto "sin reservas" definidos en RFC-3986, p.2.3

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

La implementación depende del lenguaje de programación que elija.

Si su URL contiene caracteres nacionales, primero codifíquelos en UTF-8 y luego codifique en porcentaje el resultado.


1
¿Por qué alguien debería preocuparse por la especificación HTML si el recurso solicitado no es HTML? He visto "+" en algunas API web que no responden con HTML, por ejemplo, solicita un pdf. Considero incorrecto que no usen "% 20".
El increíble Jan

@ TheincredibleJan, estoy de acuerdo contigo. De eso se trata mi respuesta.
Maxim Masiutin

1
@MaximMasiutin Cuando su respuesta dice "Esto es un MAYO, no es NECESARIO", ¿a qué especificaciones se refiere? Estoy luchando por encontrar una especificación que lo tenga como un mayo. En w3.org/TR/1999/REC-html401-19991224/interact/… el uso de '+' (en la sección de consulta) está dentro de una sección 'imprescindible' de la especificación.
JosephH

2
@JosephH: gracias por tu nota. Es mi opinión persional sobre MAYO. He editado la publicación. Lo que quise decir es que la especificación HTML que escribiste define "+", pero en el contexto de URL, se aplican otras reglas, que también permiten codificar espacios como% 20.
Maxim Masiutin
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.