Métodos GET vs POST del HTTP

Entendiendo el concepto de GET y POST

Muchas veces tenemos una idea equivocada sobre la utilización de GET y POST. Tendemos a entender que cuando doy click a un link eso es GET y cuando envío un formulario es POST. Mucho peor, solemos pensar que enviando peticiones POST los datos viajan seguros por no ir como parte de la URL como lo hace GET. Hay un error en este concepto que considero que cuando empezamos a aprender a usar tecnologías Web como por ejemplo PHP es entendible pero que a medida que vamos madurando debemos darnos cuenta que GET y POST no son la diferencia entre links y formularios.

Se suele prestar a confusión ya que tanto GET como POST son métodos del protocolo HTTP el cual esta compuesto por un envío al servidor conocido como petición (request) y una respuesta a dicha solicitud (response).

Protocolo HTTP

Tanto GET como POST, justamente por ser métodos ambos de HTTP, ejecutan un request y response, y a mi criterio esto suele ser parte de la confusión sobre los objetivos reales de ambos métodos.

Redefinamos los conceptos

El concepto GET es obtener información del servidor. Traer datos que están en el servidor, ya sea en un archivo o base de datos, al cliente. Independientemente de que para eso tengamos que enviar (request) algún dato que será procesado para luego devolver la respuesta (response) que esperamos, como por ejemplo un identificador para obtener una noticia de la base de datos.

POST sin embargo es enviar información desde el cliente para que sea procesada y actualice o agregue información en el servidor, como sería la carga o actualización en sí de una noticia. Cuando enviamos (request) datos a través de un formulario, estos son procesados y luego a través de una redirección por ejemplo devolvemos (response) alguna página con información.

Ambos métodos solicitan una respuesta del servidor y ahí es donde parecen que los conceptos son iguales ya que con ambos se podría lograr los mismos objetivos. Yo podría, aunque estaría mal, enviar por GET ciertos datos en la URL y “actualizar o insertar” información en mi base de datos, pero eso le correspondería al método POST. De la misma manera podría solicitar una página diferente por medio de POST y simplemente mostrarla como respuesta aunque eso debería ser a través de una llamada GET.

Las llamadas GET pueden ser cacheadas (historial del navegador), indexadas por buscadores, agregar los enlaces a nuestros favoritos o hasta pasar una url completa a otra persona para que directamente ingrese a esa página. Con el método POST sin embargo no se puede hacer esto.

Generalmente usamos links para ejecutar llamadas GET ya que la idea del link es simplemente “solicitar” una información (página) al servidor y que sea devuelta como una respuesta. Mientras usamos formularios para actualizar datos de productos, clientes, noticias, etc, también teniendo en cuenta que por el método POST también se puede enviar mucha más cantidad de datos que por GET.

Para entender finalmente la diferencia voy a darles un caso de análisis. Supongamos que tenemos en nuestro sitio ecommerce un listado de productos con un link que agregue ese producto al carrito de compras. Si hacemos que ese link ejecute el método GET, como generalmente lo usamos, usaríamos una URL parecida a esta: www.misitio.com/agregar_item_carrito.php?id=1. Al ser una llamada GET, Google podría indexar esa URL y podría aparecer en el buscador al buscar la palabra carrito. Cuando una persona le diera click automáticamente se ejecutaría esa página y agregaría el item con id 1 al carrito del sitio, lo cual les puedo asegurar que no es la idea ya que el visitante al buscar carrito debería querer simplemente entrar al sitio y no agregar un ítem que ni siquiera sabe cual es. Por lo tanto vemos que para este caso, por más que usemos un link, deberíamos de usar una llamada al método POST por ejemplo como lo usa el framework Symfony así:

<a onclick="f = document.createElement('form'); document.body.appendChild(f);
    f.method = 'POST'; f.action = this.href; f.submit();return false;"
    href="agregar_item_carrito.php?id=1">Agregar al carrito</a>

Lo que hace este link es muy sencillo, por medio del evento onclick de JavaScript, crea dinámicamente un formulario, le dice que será POST (ya que por defecto sería GET), le asigna la URL del enlace al action del form, envía el formulario y retorna false para no ejecutar el link en sí. Para hacer esto con Symfony simplemente usamos el helper link_to agregando la opción post=true:

<?php echo link_to('Agregar al carrito', 'agregar_item_carrito.php?id=1', 'post=true') ?>

Otro ejemplo sencillo sería cuando en un administrador de noticias tenemos un listado de las noticias con un link “eliminar” para borrarlas una por una (situación muy común en sistemas Web). Deberíamos de hacer esta petición usando POST para no permitir, por seguridad, que esa URL creada sea indexada, enviada a otra persona, guardada en favoritos, ni mucho menos ejecutada por culpa del botón atrás del navegador ya que quedaría cacheada en el historial.

Demos un ejemplo opuesto. Hay casos en los que los formularios de búsquedas al ser enviados por POST van a la página de resultados pero como estas llamadas no son cacheadas en el historial del navegador, no podemos volver usando la tecla atrás del navegador por lo que se suele dejar como llamadas GET a fin de ser cacheadas. Esto lo hacemos simplemente poniendo en el method del form la palabra get en lugar de post.

Espero que con esto se haya entendido la diferencia real entre los métodos GET y POST del protocolo HTTP y que cuando vayamos a utilizar un link o un formulario nos detengamos a pensar dos veces cual método es el más apropiado para no arriesgar la seguridad ni la consistencia del sitio.

Este es un artículo interesante para continuar con este tema.

En el siguiente artículo vamos a hablar sobre la forma de utilizar estos dos métodos con Ajax y jQuery.

Los comentarios son bienvenidos.

24 responses

  1. Genial artículo, tengo mucho de no programar para web y estoy retomándolo, así que lo primero que vino a mi mente fue esta cuestión; ya no recordaba la explicación que me dieron en la escuela.
    Me ayudó mucho, lo explicas de manera que no hay lugar a dudas.

    Bien.

  2. Muy buen artículo. Sobre todo muy didáctico y sencillo. No soy programador sino que hago gestión. Pero para entender lo que me estaban solicitando busqué, encontré tu artículo y ahora entiendo lo que me están pidiendo. Muchas gracias.

  3. Genial el artículo, me encuentro en la misma situación que Evelyn, desentumeciendo neuronas después de una buena temporada sin programar. Es curioso, lo importante que puede ser una cosa que a simple vista parece tan simple como el método del formulario.

    Muchas gracias por tu aporte a la comunidad ;)

    Seguiré de cerca tu blog.

    Un saludo!

  4. Gracias por el articulo, esta muy claro y con muy buenos ejemplos.

    Aun así tengo una duda al respecto. ¿Por que se usa un link para añadir un articulo y después se genera un formulario con javascript y no se hace con un formulario desde el principio?

    Gracias de nuevo.

    • Dani. Este caso de suele utilizar cuando en lugar de poner como link el texto que ahora figura “Agregar al carrito”, quieres usar una imagen y lo puedes hacer rápidamente aprovechando una funcionalidad que existía en la versión.

      De todas formas la idea es ilustrar que generalmente cuando vemos un link, pensamos en GET, pero en realidad tiene ver con el objetivo, y en ese caso es POST ya que se quiere agregar un recurso.

  5. Gracias! La verdad es que cometía todos los fallos (confusiones) que mencionas.
    Ahora, al entender que GET puede ser cacheado o compartido como enlace se me aclara absolutamente todo.
    Oye… ¡que me has quitado una astilla que tenía clavada!
    Un saludo.

  6. Gracias por la información, es cierto y parte del problema es que muchos de los tutoriales de HTML, PHP y demás te dan a entender que entre POST y GET no hay diferencia salvo que la información está visible en la URL con GET siendo lo contrario con POST.

    Una duda que me quedaría es; En el ejemplo final que das de eliminar las noticias de un listado mencionas que se usaría POST para ello, y yo me pregunto ¿No se debería utilizar la petición DELETE de HTTP? Pregunto esto porque en dado caso pienso que sería el uso correcto del protocolo HTTP de otra manera quizá estaríamos cayendo en el mismo error de utilizar peticiones HTTP como nos funcione y no para lo que fueron creadas.

    ¿Estoy equivocado?

    Saludos.

    • Estas completamente en lo cierto Roberto. Lo correcto es usar los verbos HTTPP para todas las acciones como lo puedes ver en los artículos que escribí sobre servicios REST. Para este artículo tomo en cuenta el POST para insert, update y delete porque es un siguiente paso tomando en cuenta que hay ocasiones en donde existen problemas con los navegadores a la hora de querer usar un verbo diferente a GET y POST por ejemplo en el action de un form y no te queda otra que usar un POST.

      Cuando trabajas con servicios REST ya es más fácil ya que por lo general no es el navegador el que invoca a los servicios, sino el action de tu front-end, y este es invocado desde un form por ejemplo.

  7. Muchas gracias, sos groso. Hace tres días empecé a aprender Java EE porque en todos los trabajos me los están requiriendo y nada mejor que comenzar a aprender una nueva tecnología usando buenos prácticas desde el comienzo.

    Saludos!

Comenta este artículo