Saltar al contenido principal

Guías / Códigos de estado HTTP explicados

303 See Other: la redirección tras un POST de formulario

303 See Other le dice al cliente que la petición se procesó y que el resultado está en otra URL, a la que debería acceder con GET. Es la respuesta correcta al envío de un formulario que debería dejar al visitante en una página de resultado o confirmación en lugar de dejarlo sobre el propio POST.

Para qué sirve el 303

Un 303 no trata realmente de mover un recurso. Trata de separar una acción de su resultado. El cliente envía un POST, el servidor realiza la acción, y en lugar de devolver el resultado en la respuesta del POST, responde con 303 y una cabecera Location. El cliente hace un GET nuevo a esa ubicación, y la barra de direcciones del navegador termina en una URL normal que se puede guardar en marcadores y recargar.

La regla que lo define es el método: sea cual sea el método de la petición original, la petición de seguimiento a la URL de Location es un GET. Eso es lo contrario de 307 y 308, que exigen conservar el método y el cuerpo originales.

Post/Redirect/Get, y el problema que resuelve

Sin una redirección tras un POST, la página de resultado pertenece a la petición POST, lo que causa problemas conocidos:

  • Pulsar recargar vuelve a enviar el formulario, así que el pedido se realiza o el comentario se publica dos veces. Los navegadores avisan de esto con un diálogo de "confirmar reenvío de formulario", que es en sí mismo una mala experiencia.
  • La página no se puede guardar en marcadores ni compartir, porque la URL no describe el contenido.
  • El botón atrás lleva a un aviso de reenvío en lugar de a la página anterior.

Post/Redirect/Get soluciona todo esto. El POST realiza la acción y responde 303; el navegador hace GET a la URL de resultado; una recarga ahora simplemente vuelve a obtener una página inofensiva. Por eso casi todos los frameworks tienen un ayudante de "redirigir tras guardar".

303 frente a 302 frente a 307

  • 302 Found es una redirección temporal cuyo manejo del método es históricamente ambiguo. La mayoría de los clientes convierten un POST en un GET al seguirlo, que suele ser lo que se pretendía, pero el estándar no lo exige. Muchos frameworks todavía emiten 302 para el patrón post-y-luego-redirige y funciona en la práctica.
  • 303 See Other hace ese comportamiento explícito y obligatorio. Si tu intención es "no repitas mi POST, ve y haz GET a esto", 303 lo dice sin ambigüedad.
  • 307 Temporary Redirect es el que hay que evitar aquí. Exige repetir el POST contra la nueva URL, lo que para el envío de un formulario significa realizar la acción dos veces.

Una salvedad práctica: el 303 se introdujo en HTTP/1.1, así que un cliente que hable HTTP/1.0 puede no entenderlo. Algunos frameworks usan 302 por defecto por esa razón. En la web moderna casi nunca es una limitación real, pero explica la diferencia de valores por defecto que verás entre lenguajes.

Dónde más aparece el 303

  • APIs que inician trabajo de larga duración. Un POST pone en marcha una tarea y responde 303 con la URL de estado de esa tarea, o 202 con una URL de estado en el cuerpo. Ambos patrones están en uso; 303 tiene la ventaja de que un navegador lo sigue automáticamente.
  • Flujos de OAuth e inicio de sesión. Algunos servidores de autorización redirigen de vuelta a la aplicación cliente con un 303 para que el callback se obtenga con GET sin importar cómo llegó la petición.
  • Configuraciones de datos enlazados y negociación de contenido que distinguen una cosa del mundo real del documento que la describe, y usan 303 para enviar a los clientes del identificador al documento.

Cómo usarlo y verificarlo

  1. Tras un POST correcto, devuelve 303 con una Location absoluta que apunte a la página de resultado. No renderices el resultado en línea.
  2. Haz que el destino sea idempotente. Se va a obtener de nuevo en cada recarga y cada navegación hacia atrás, así que tiene que ser seguro hacerle GET repetidamente.
  3. Lleva cualquier mensaje puntual, como "tus cambios se guardaron", en el estado de sesión o en un parámetro de consulta en lugar de en el cuerpo de la redirección. El cuerpo de una respuesta 303 normalmente no se muestra.
  4. Verifica el código y el destino:
    curl -si -X POST -d "name=test" https://example.com/submit | grep -Ei "^(HTTP|location)"
    Deberías ver HTTP/1.1 303 See Other y la URL de resultado.
  5. Síguelo y confirma que la segunda petición es un GET que devuelve 200. Si ves un POST repetido en los registros de tu servidor, la regla es un 307 y hay que cambiarla.
  6. Comprueba que el destino no es a su vez otra redirección. Un 303 hacia un 301 hacia la página real son tres idas y vueltas para el envío de un solo formulario.

Monitorizar los endpoints detrás de un formulario

Un flujo roto de post-y-luego-redirige es invisible para una comprobación que solo obtiene la página de inicio. El sitio está activo, el formulario se renderiza, y solo las personas que lo envían se topan con el fallo. Detéctalo pronto vigilando los endpoints detrás de la acción, como la página de resultado, la URL de confirmación y la ruta de estado de la tarea, y comprobando el código de estado y el contenido esperados en cada uno. HostTracker ofrece 13 tipos de monitor y avisa por correo, SMS, llamada de voz, Slack, Telegram y más. Comprueba lo que devuelve cualquier URL con la herramienta de comprobación HTTP, y lee 301 frente a 302 y la guía completa de la familia de redirecciones 3xx para los códigos vecinos.

Compruébalo ahora

Ejecuta la comprobación gratuita en tu propio sitio, sin necesidad de cuenta.

HTTP check

Monitoriza esto de forma permanente

Recibe un aviso en cuanto algo falle: HostTracker comprueba desde más de 300 ubicaciones y te avisa por correo, SMS, Slack, Telegram y más.

Funciones de HostTracker

Más en esta sección: Códigos de estado HTTP explicados