2009-03-18 11 views
37

Tengo una aplicación que proporciona una larga lista de parámetros para una página web, así que tengo que usar POST en lugar de GET. El problema es que cuando se muestra la página y el usuario hace clic en el botón Atrás, Firefox muestra una advertencia:Impedir que el botón Atrás muestre la alerta de confirmación POST

Para mostrar esta página, Firefox debe enviar información que repetirá cualquier acción (como una búsqueda o confirmación del pedido) eso fue realizado antes.

Dado que la aplicación está construida de tal manera que volver es una operación bastante común, esto es realmente molesto para los usuarios finales.

Básicamente, me gustaría hacerlo de la manera que hace esta página:

http://www.pikanya.net/testcache/

Introduzca algo, enviar y haga clic en el botón Volver. Sin advertencia, solo regresa.

Google Descubrí que esto podría ser un error en Firefox 3, pero de alguna manera me gustaría obtener este comportamiento incluso después de que lo "corrijan".

Supongo que podría ser factible con algunos encabezados HTTP, pero ¿con exactitud?

+0

Sólo por lo que aseguro que sé lo que está pasando aquí, se puede pegar el texto de la advertencia? –

+0

La página que vinculó no elimina la advertencia. Aún veo: Confirmar Para mostrar esta página, Firefox debe enviar información que repita cualquier acción (como una búsqueda o confirmación de pedido) realizada anteriormente. [Reenviar] [Cancelar] – Sparr

+0

No si usa Firefox 3.0.6 o una versión similar. Probablemente tengas un navegador donde haya sido "arreglado". –

Respuesta

27

Una vuelta es redirigir la POST a una página que redirige a un GET - ver Post/Redirect/Get on wikipedia.

Supongamos que su POST es 4K de datos del formulario. Es de suponer que su servidor hace algo con esa información en lugar de solo mostrarla una vez y tirarla, como guardarla en una base de datos. Siga haciendo eso, o si se trata de un gran formulario de búsqueda, cree una copia temporal en una base de datos que se depura después de unos días o en una LRU cuando se utiliza un límite de espacio. Ahora crea una representación de los datos a los que se puede acceder usando GET. Si es temporal, genere una identificación y utilícela como URL; si se trata de un conjunto permanente de datos, probablemente tenga una ID o algo que pueda usarse para la URL. En el peor de los casos, un algoritmo como los pequeños usos de url puede colapsar una gran URL a una mucho más pequeña. Redirigir el POST para OBTENER la representación de los datos.


Como nota histórica, esta técnica fue established practice in 1995.

+1

¿Pero cómo? Los datos de entrada son más de 4kB y la salida de página depende de ello. –

+0

Parece que tendré que hacerlo de esta manera, a menos que haya algún truco con el caché. –

+1

no use ningún truco y hágalo exactamente de la manera sugerida por Pete. Lo que me gusta de su solución es que sigue principios simples de REST. –

3

Una forma de evitar esa advertencia/comportamiento es hacer el POST a través de AJAX, luego enviar al usuario a otra página (o no) por separado.

+1

Sí, ese es mi plan de copia de seguridad. Pero el botón ATRÁS no funciona con AJAX, así que tendré que implementar mi propio "controlador de respaldo" en ese caso, lo cual quiero evitar. –

37

Ver mi regla de oro de la programación web aquí:

Stop data inserting into a database twice

Dice: “Nunca jamás responderá con un cuerpo a un post-petición. Haga siempre el trabajo, y luego responda con un encabezado Location: para redirigir a la página actualizada para que el navegador lo solicite con GET "

Si el navegador alguna vez pregunta al usuario sobre volver a enviar, su aplicación web está rota. El usuario no debería ver esta pregunta.

+0

Para producir la página web necesito suministrar aproximadamente 4k de entrada. No puedo hacer eso con GET. No hay "trabajo" por hacer, la salida en sí depende de los parámetros dados.Lo único que se me ocurre es almacenar esos 4k de datos en la sesión PHP y recuperarlos en la solicitud GET, pero si el usuario tiene ... –

+0

... pestañas abiertas de mi aplicación, eso no funcionaría. –

+8

Parece que Amazon no sigue esta regla de oro –

1

Tengo una aplicación que proporciona una larga lista de parámetros para una página web, así que tengo que usar POST en lugar de GET.El problema es que cuando se muestra la página y el usuario hace clic en el botón Atrás, Firefox muestra una advertencia:

Su razonamiento es incorrecto. Si la solicitud no tiene efectos secundarios, se debe OBTENER. Si tiene efectos secundarios, debe ser POST. La elección no debe basarse en la cantidad de parámetros que debe aprobar.

+3

No hay ningún efecto secundario, pero los parámetros son 4kB. En caso de que no lo supiera, GET tiene un límite de 1024 bytes. –

+0

¿Qué tipo de parámetros ocupan tanto espacio? ¿Puede explicar el contexto de su aplicación un poco más? – troelskn

+0

Supongamos que es una búsqueda de imagen inversa, donde los datos de la publicación son una imagen. –

2

He estado usando la variable Session para ayudar en esta situación. Esto es el método que utilizo que ha estado trabajando muy bien para mí durante años:

//If there's something in the POST, move it to the session and then redirect right back to where we are 
if ($_POST) { 
    $_SESSION['POST']=$_POST; 
    redirect($_SERVER["REQUEST_URI"]); 
} 

//If there's something in the SESSION POST, move it back to the POST and clear the SESSION POST 
if ($_SESSION['POST']) { 
    $_POST=$_SESSION['POST']; 
    unset($_SESSION['POST']); 
} 

Técnicamente, incluso no es necesario ponerlo de nuevo en una variable llamada $ _POST. Pero me ayuda a hacer un seguimiento de qué datos provienen de dónde.

0

Como otra solución, puede dejar de usar el redireccionamiento.

Puede procesar y representar el resultado de procesamiento de una vez sin POST alerta de confirmación. Usted sólo debe manipular el objeto historial del navegador:

history.replaceState("", "", "/the/result/page") 

Ver full o short responde

Cuestiones relacionadas