¿Cómo se envían los parámetros en una solicitud HTTP POST?
En una solicitud HTTP GET , los parámetros se envían como una cadena de consulta :
http://example.com/page ?parameter=value&also=another
En una solicitud HTTP POST , los parámetros no se envían junto con el URI.
¿Dónde están los valores? ¿En el encabezado de la solicitud? ¿En el cuerpo de la solicitud? Cómo se ve?
Los valores se envían en el cuerpo de la solicitud, en el formato que especifica el tipo de contenido.
Normalmente el tipo de contenido es application/x-www-form-urlencoded
, por lo que el cuerpo de la solicitud utiliza el mismo formato que la cadena de consulta:
parameter=value&also=another
Cuando utilizas la carga de un archivo en el formulario, utilizas la multipart/form-data
codificación, que tiene un formato diferente. Es más complicado, pero normalmente no es necesario que te importe su apariencia, así que no mostraré un ejemplo, pero puede ser bueno saber que existe.
Respuesta corta: en las solicitudes POST, los valores se envían en el "cuerpo" de la solicitud. En el caso de los formularios web, lo más probable es que se envíen con un tipo de medio application/x-www-form-urlencoded
o multipart/form-data
. Los lenguajes o marcos de programación que han sido diseñados para manejar solicitudes web generalmente hacen "Lo correcto™" con dichas solicitudes y le brindan fácil acceso a los valores fácilmente decodificados (como $_REQUEST
o $_POST
en PHP, o cgi.FieldStorage()
, flask.request.form
en Python).
Ahora divaguemos un poco, lo que puede ayudar a comprender la diferencia;)
La diferencia entre las solicitudes GET
y POST
es en gran medida semántica. También se "utilizan" de manera diferente, lo que explica la diferencia en cómo se pasan los valores.
OBTENER ( sección RFC relevante )
Al ejecutar una GET
solicitud, le solicita al servidor una o un conjunto de entidades. Para permitir que el cliente filtre el resultado, puede utilizar la llamada "cadena de consulta" de la URL. La cadena de consulta es la parte que sigue al ?
. Esto es parte de la sintaxis de URI .
Entonces, desde el punto de vista del código de su aplicación (la parte que recibe la solicitud), deberá inspeccionar la parte de la consulta URI para obtener acceso a estos valores.
Tenga en cuenta que las claves y los valores son parte del URI. Los navegadores pueden imponer un límite a la longitud del URI. El estándar HTTP establece que no hay límite. Pero al momento de escribir este artículo, la mayoría de los navegadores limitan los URI (no tengo valores específicos). Las solicitudes nuncaGET
deben usarse para enviar nueva información al servidor. Especialmente no documentos más grandes. Ahí es donde debes usar o .POST
PUT
POST ( sección RFC relevante )
Al ejecutar una POST
solicitud, el cliente en realidad envía un nuevo documento al host remoto. Por lo tanto, una cadena de consulta no tiene sentido (semánticamente). Es por eso que no tiene acceso a ellos en el código de su aplicación.
POST
es un poco más complejo (y mucho más flexible):
Al recibir una solicitud POST, siempre debe esperar una "carga útil" o, en términos HTTP: un cuerpo de mensaje . El cuerpo del mensaje en sí mismo es bastante inútil, ya que no existe un formato estándar (hasta donde yo sé. ¿Quizás aplicación/flujo de octetos?). El formato del cuerpo está definido por el Content-Type
encabezado. Cuando se utiliza un FORM
elemento HTML con method="POST"
, suele ser application/x-www-form-urlencoded
. Otro tipo muy común es multipart/form-data si utiliza la carga de archivos. Pero podría ser cualquier cosa , desde text/plain
, sobre application/json
o incluso una costumbre application/octet-stream
.
En cualquier caso, si POST
se realiza una solicitud con un código Content-Type
que la aplicación no puede manejar, debería devolver un 415
código de estado .
La mayoría de los lenguajes de programación (y/o marcos web) ofrecen una forma de decodificar el cuerpo del mensaje desde/hacia los tipos más comunes (como application/x-www-form-urlencoded
o multipart/form-data
) application/json
. Entonces eso es fácil. Los tipos personalizados requieren potencialmente un poco más de trabajo.
Utilizando un documento codificado con un formulario HTML estándar como ejemplo, la aplicación debe realizar los siguientes pasos:
- leer el
Content-Type
campo - Si el valor no es uno de los tipos de medios admitidos, devuelva una respuesta con un
415
código de estado - de lo contrario, decodifica los valores del cuerpo del mensaje.
Nuevamente, lenguajes como PHP o frameworks web para otros lenguajes populares probablemente se encargarán de esto por usted. La excepción a esto es el 415
error. Ningún marco puede predecir qué tipos de contenido su aplicación elige admitir y/o no. Esto depende de ti.
PUT ( sección RFC relevante )
Una PUT
solicitud se maneja prácticamente de la misma manera que una POST
solicitud. La gran diferencia es que se supone que una POST
solicitud debe permitir al servidor decidir cómo (y si lo hace) crear un nuevo recurso. Históricamente (a partir del ahora obsoleto RFC2616 era crear un nuevo recurso como "subordinado" (hijo) del URI donde se envió la solicitud).
PUT
Por el contrario, se supone que una solicitud "deposita" un recurso exactamente en ese URI y con exactamente ese contenido. Ni mas ni menos. La idea es que el cliente sea responsable de elaborar el recurso completo antes de "PONERLO". El servidor debería aceptarlo tal cual en la URL proporcionada.
Como consecuencia, POST
normalmente no se utiliza una solicitud para reemplazar un recurso existente. Una PUT
solicitud puede crear y reemplazar.
Nota al margen
También hay " parámetros de ruta " que se pueden usar para enviar datos adicionales al control remoto, pero son tan poco comunes que no entraré en demasiados detalles aquí. Pero, como referencia, aquí hay un extracto del RFC:
Aparte de los segmentos de puntos en rutas jerárquicas, la sintaxis genérica considera que un segmento de ruta es opaco. Las aplicaciones productoras de URI suelen utilizar los caracteres reservados permitidos en un segmento para delimitar subcomponentes específicos del esquema o del controlador de desreferencia. Por ejemplo, los caracteres reservados punto y coma (";") e igual ("=") se utilizan a menudo para delimitar parámetros y valores de parámetros aplicables a ese segmento. El carácter reservado coma (",") se utiliza a menudo para fines similares. Por ejemplo, un productor de URI podría usar un segmento como "nombre;v=1.1" para indicar una referencia a la versión 1.1 de "nombre", mientras que otro podría usar un segmento como "nombre,1.1" para indicar lo mismo. Los tipos de parámetros pueden definirse mediante semántica específica del esquema, pero en la mayoría de los casos la sintaxis de un parámetro es específica de la implementación del algoritmo de desreferenciación de URI.
El contenido se coloca después de los encabezados HTTP. El formato de un HTTP POST debe tener los encabezados HTTP, seguidos de una línea en blanco y del cuerpo de la solicitud. Las variables POST se almacenan como pares clave-valor en el cuerpo.
Puede ver esto en el contenido sin formato de una publicación HTTP, que se muestra a continuación:
POST /path/script.cgi HTTP/1.0
From: [email protected]
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
home=Cosby&favorite+flavor=flies
Puede ver esto usando una herramienta como Fiddler , que puede usar para observar la solicitud HTTP sin procesar y las cargas de respuesta que se envían a través del cable.
No puede escribirlo directamente en la barra de URL del navegador.
Puede ver cómo se envían los datos POST en Internet con encabezados HTTP en vivo, por ejemplo. El resultado será algo así.
http://127.0.0.1/pass.php
POST /pass.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://127.0.0.1/pass.php
Cookie: passx=87e8af376bc9d9bfec2c7c0193e6af70; PHPSESSID=l9hk7mfh0ppqecg8gialak6gt5
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
username=zurfyx&pass=password
En donde dice
Content-Length: 30
username=zurfyx&pass=password
serán los valores de la publicación.
El tipo de medio predeterminado en una solicitud POST es application/x-www-form-urlencoded
. Este es un formato para codificar pares clave-valor. Las claves pueden estar duplicadas. Cada par clave-valor está separado por un &
carácter y cada clave está separada de su valor por un =
carácter.
Por ejemplo:
Name: John Smith
Grade: 19
Está codificado como:
Name=John+Smith&Grade=19
Esto se coloca en el cuerpo de la solicitud después de los encabezados HTTP.
Los valores de formulario en HTTP POST se envían en el cuerpo de la solicitud, en el mismo formato que la cadena de consulta.
Para obtener más información, consulte las especificaciones .