En programación HTTP, peticiones tipo POST suplen data adicional del cliente (el buscador, o "browser") al servidor en el cuerpo del mensaje. Como contraste, las peticiones tipo GET incluyen toda la data requerida en el enlace (el URL, siglas en inglés). Formularios en HTML pueden usar cualquier método, usando method="POST" o method="GET" (default) en el elemento <form>. El método especificado determina cómo es que la data del formulario será enviada al servidos. Cuando el método es GET, toda la data del formulario se codifica dentro del URL, apegado al URL de acción, como parámetros de la petición directa (query string). Con POST, la data del formulario aparece dentro del cuerpo del mensaje de petición de HTTP.
Tabla de comparación
GET | POST | |
---|---|---|
Historial | Los parámetros se guardan en el historial del buscador (browser) porque son parte del enlace (URL) | No se guardan los parámetros en el historial del buscador |
Archivación (bookmark) | Puede ser archivado | No puede ser archivado |
Resultado al usar BACK/resometer petición | Las peticiones GET se ejecutan de nuevo pero no se pueden re-someter al servidor si el HTML está guardado en el almacenaje (cache) del "browser" | El "browser" usualmente le avisa al usuario que la data tiene que ser re-sometida |
Tipo de codificación (atributos enctype) | application/x-www-form-urlencoded | multipart/form-data o application/x-www-form-urlencoded |
Parámetros | Puede enviarlos pero la data de parámetros está limitado a lo que cabe en el URL. Es más seguro usar menos de 2K de los parámetros (algunos servidores llegan a 64K) | Puede enviar parámetros, incluyendo subir archivos al servidor |
Vulnerabilidad | Más fácil de atacar | Más difícil de atacar |
Restricciones en el tipo de data en el formulario | Sí, sólo se permiten caracteres ASCII | No tiene restricciones. Se permite data binaria. |
Restricciones en la cantidad de data en formularios | Sí porque la data del formulario está en el URL y hay un límite para URLS de 2,048 caracteres, aunque puede variar | No tiene restricciones |
Usabilidad | El método GET no se debe usar para enviar claves de entrada o cualquier información sensitiva | POST se debe usar para enviar claves de entrada o cualquier información sensitiva |
Visibilidad | GET está visible para todo el mundo (en la barra de URLS del buscador) y tiene límites a la cantidad de data que puede enviar | La variables en POST no se ven en los URLs |
Almacenable | Se puede almacenar | No se puede almacenar |
Valores de variables grandes | Límite de 7,607 caracteres | Límite de 8 MB |
Diferencias en someter formularios
la diferencia fundamental entre METHOD="GET" y METHOD="POST" es que corresponden a diferentes peticiones de HTTP, según se define en las especificaciones de HTTP. El proceso de someter data para ambos métodos comienza de la misma manera - el buscador (browser) construye un set de data del formulario y la codifica según los atributos dados. Para METHOD= "POST" el atributo enctype puede ser multipart/form-data o application/x-www-form-urlencoded, mientras que en METHOD="GET", sólo se permite application/x-www-form-urlencoded. El set de data del formulario se transmite al servidor.
Para someter el set de data del formulario bajo METHOD="GET", el "browser" construye el enlace (URL) tomando el valor del atributo action, le añade un ? a eso, entonces apega el set de data del formulario (codificado usando el tipo de contenido bajo application/x-www-form-urlencoded.) El "browser" entonces procesa el enlace como argumento (argument). El servidor lo toma de ahí en adelante. Nota que este proceso significa que la data del formulario está restringida a códigos ASCII. Hay que tener cuidado para codificar y decodificar ambos tipos de caracteres cuando se pasan a un enlace (URL) en formato ASCII.
Someter un formulario (form) usando METHOD="POST" causa que se envíe una petición POST usando el valor del atributo action creado de acuerdo al tipo de contenido especificado por el atributo enctype.
Pros y contras
Como la data del formulario se envía como parte del enlace cuando se usa GET:
- La data del formulario está restringido a códigos ASCII, requiriendo cuidado especial para codificar y decodificar los mismos. Por otro lado, data binaria, imágenes y otros archivos se pueden enviar todos por METHOD="POST".
- Toda la data del formulario está visible en el URL (enlace). Además, esto se guarda en el historial de búsquedas del usuario dentro del "browser," Esto hace que GET sea menos seguro.
- Sin embargo, hay una ventaja en enviar la data del formulario como parte del URL: uno puede guardar los enlaces y usarlos directamente, pasando por alto todo el proceso de llenar formularios.
- Hay una limitación en cuanta a la data que se puede enviar porque los enlaces tienen límites de caracteres.[1]
- Es más fácil exponer vulnerabilidades en el sistema para hacerle ataques (hacks). Por ejemplo, Citibank fue atacado al cambiar números de cuentas en los enlaces.[2] Por supuesto, se pueden exponer estas vulnerabilidades si se usa POST, pero es in poco más difícil. En general, el servidor siempre debe estar sospechoso de cualquier data que envía un cliente y tener cuidado de Referencias de Objetos Directos Inseguros (Insecure Direct Object References).
Diferencias en procesamiento en servidores
En principio, el procesamiento de la data de formulario depende de si fue enviado por METHOD="GET" o METHOD="POST". Como la data se codifica de maneras diferentes, se necesitan diferentes mecanismos de decodificación. Por lo tanto, cambiar el METHOD puede necesitar un cambio en la programación que procesa la data. Por ejemplo, en una interfaz de imágenes gráficas de computadora (CGI, en inglés), se recibe la data en una variable ambiental (environment variable QUERYSTRING) cuando se usa GET. Pero cuando se usa POST, la data se pasa en un flujo estándar de entrada (stdin) y el número de bits a leerse lo da el encabezado (header) del contenido (Content-length).
Usos recomendados
GET se recomienda para someter formularios tipo "idempotent," o sea, aquellos que "no alteran el mundo de forma significativa." Eso usualmente se refiere a peticiones de bases de datos solamente. Otra perspectiva es que varias peticiones tipo idempotent pueden tener el mismo efecto de una sola petición. Si la base de datos requiere ponerse al día a menudo o hay otras acciones a tomarse (enviar emails, por ejemplo), se recomienda usar POST.
Del blog de desarrollo de Dropbox:
Un buscador no sabe lo que un formulario de HTML hace, pero si el formulario se somete via HTTP GET. el buscador sabe que es seguro tratar de nuevo a buscar la información si hay un error en la red. Para formularios que usan HTTP POST, puede que no sea seguro tratar de nuevo, así que el buscador le pregunta primero al usuario para una confirmación.
Una petición "GET" es almacenable (cacheable), mientras que las peticiones "POST" apenas lo son. Para sistemas de peticiones esto puede tener un impacto significativo en eficiencia, especialmente si las peticiones son simples, ya que se pueden almacenar las más frecuentes.
En ciertos casos, es mejor usar POST aún para peticiones tipo idempotent:
- Si la data del formulario contiene caracteres que no son de ASCII (como acentos en vocales), entonces METGOD="GET" no es aplicable, aunque sí se puede usar con caracteres ISO Latino 1.
- Si el set de data del formulario es grande, dígase de cientos de caracteres, entonces METHOD="GET" puede causar problemas de implementación al no poder manejar URLs largos.
- Es bueno evitar METHOD="GET" para que sea menos visible a usuarios como es que funciona el formulario, en especial al crear campos "invisibles" (hidden fields, INPUT TYPE="HIDDEN"). Pero aunque use campos invisibles con METHOD="POST", siguen apareciendo en la programación codificada en HTML.
Referencias
Comentarios: GET (HTTP) vs POST (HTTP)