2009-03-20 10 views
20

Estoy haciendo desarrollo web.¿Cómo impido que los botones Atrás y Actualizar vuelvan a enviar mi formulario?

Tengo una página que ver con la tarjeta de crédito, que cuando el usuario hace clic en "actualizar" o "Atrás", la transacción se realizará una vez más, lo que no es deseado.

Esto incluye el buscador arriba a la izquierda "Atrás" & botón "Actualizar", "clic derecho-> Actualizar/Atrás", presione la tecla "F5". Esto se debe hacer en cierta página de cgi solamente, no en todas.

¿Se puede hacer esto mediante el uso de Javascript? O cualquier otro método?

Respuesta

48

El standard way es hacerlo en 3 pasos.

  1. la página de formulario envía campos de página de procesamiento
  2. página de procesamiento procesa los datos y redirecciona a la pagina de resultados
  3. página de resultados sólo muestra resultados, la recarga no hará ningún daño.
+14

también conocido como el post-redirección-Get patrón. – Rob

+22

Esto no impide que el formulario sea reprocesado si el usuario pulsa "Atrás" (si le dicen a su navegador que vuelva a enviar) – philfreo

+4

@ philfreo, de hecho, lo previene. La mayoría de los marcos de hoy emitirán un encabezado "302 Moved", que efectivamente le dice al navegador que use la página de resultados para el historial durante la navegación del botón de retroceso. –

11

Esto rompe el modelo básico de experiencia del usuario del navegador ... los usuarios siempre deberían poder usar los botones Actualizar y Atrás en su navegador. Recomienda que arregle su página de otra manera.

Si actualiza su pregunta para incluir el idioma/plataforma/tecnología del servidor que está utilizando, entonces alguien podría sugerir una solución.

0

VarTec: Solución s resuelve la recarga-problema, no la espalda a los problemas, por lo que aquí son una solución a eso:

  1. La página de forma fija una variable de sesión, por ejemplo de sesión ("fromformpage") = 1
  2. La página de procesamiento comprueba la variable de sesión, si es = "1" luego procesa los datos y redirige a la página de resultados si es diferente de = "1" y luego simplemente redirige a la página de resultados.
  3. La página de resultados establece la variable de sesión en "".

Luego, si el usuario está presionando el botón Atrás, la página de procesamiento no volverá a realizar el proceso, solo lo redirigirá a la página de proceso.

+2

El botón Atrás no lo llevaría a la página de procesamiento de todos modos. Lo llevará directamente a la página de formulario. – vartec

+1

todavía, es un problema que debe ser atendido. – Stefan

2

No intente "bloquear" estas acciones. Lo que debe hacer es asegurarse de que no ocurra nada cuando alguien "envía dos veces" el formulario.

7

El simple hecho de que volver a enviar el formulario genera una transacción duplicada es preocupante. Debe tener algún tipo de control para asegurarse de que cada envío de datos de formulario sea único.

Por ejemplo, la página que enviaría el formulario debería recibir un ID único que se envía con el formulario. La lógica de negocio debería poder reconocer que el formulario enviado ya se ha procesado (ya que el ID (ya no será único) será el mismo), por lo que se ignora el segundo intento.

La 'forma estándar' aún no impide que los clientes hagan clic dos veces en el botón Atrás ... o incluso que vuelvan atrás y vuelvan a enviar el formulario si no creen (por alguna razón) que se ha procesado.

1

y en algún navegador ni siquiera puedes hacer eso, ¡y esto es bueno!

1

La mejor manera es tener suficiente lógica de manejo de sesión que pueda reconocer el segundo (y posterior) intento como "esto es solo una nueva presentación" e ignórelo.

3

Coloque este código en la página de formulario

Response.Cache.SetCacheability(HttpCacheability.NoCache); 

Response.Cache.SetExpires(DateTime.Now-new TimeSpan(1,0,0)); 

Response.Cache.SetLastModified(DateTime.Now); 

Response.Cache.SetAllowResponseInBrowserHistory(false); 
+0

¿Qué se supone que debe hacer este código? ¿Vencer la página cuando el usuario pulse el botón Atrás? – vsingh

+3

+1 Ese es el código C# que hará que el navegador entregue una advertencia de "Página caducada" si un usuario intenta hacer clic en "Atrás" en su navegador – Jimbo

5
  1. generar una cadena aleatoria y almacenarlo en la sesión,

  2. entonces la salida a su forma como un valor oculto,

  3. compruebe la variable enviada y almacenada, si las coincidencias procesan su solicitud,

  4. ir a 1.

+0

¿Qué quiere decir con "valor de la tienda"? – FrostyStraw

0

me encontré con lo anterior Mensaje/Redirigir/Obtener explicaciones un poco ambiguas

Esto es lo que he seguido y es de esperar que ayude a alguien en el futuro

http://wordsideasandthings.blogspot.ca/2013/04/post-redirect-get-pattern-in-php.html

Esencialmente el proceso basado en la solución anterior es:

  1. enviarían desde la página del formulario de la página de procesamiento (o para sí mismo)
  2. base de datos de la manija o el procesamiento de pagos, etc.
  3. Si se requieren mensajes de retroalimentación almacén del usuario en una variable de sesión, posibles mensajes, error, etc.
  4. Realizar encabezado redirigir a la página de resultados (o a la página de formulario original). Si es necesario, muestra un mensaje personalizado desde la página de procesamiento. Tales como "Error al rechazar el pago con tarjeta de crédito" y restablecer las variables de sesión.

redirigida con algo como:

header("HTTP/1.1 303 See Other"); 
header("Location: http://$_SERVER[HTTP_HOST]/yourfilehere.php"); 
die(); 

El redireccionamiento de cabecera iniciará una solicitud GET en "yourfilehere.php", debido a una redirección es simplemente eso, una "petición" para obtener los datos desde el servidor , NO es POST que envía datos AL servidor. Por lo tanto, el redireccionamiento/GET impide que se produzca más procesamiento de DB/pagos después de una actualización. El estado de error 301 ayudará con presionar el botón Atrás.

lectura útil:

  1. http://en.wikipedia.org/wiki/URL_redirection#HTTP_status_codes_3xx
  2. http://www.theserverside.com/news/1365146/Redirect-After-Post
  3. http://wordsideasandthings.blogspot.ca/2013/04/post-redirect-get-pattern-in-php.html
  4. https://en.wikipedia.org/wiki/HTTP#Request_methods
  5. http://en.wikipedia.org/wiki/Post/Redirect/Get
0

sólo hay que poner este j avascript en la sección HTML de la página aspx por encima de la sección de cabeza

<script type = "text/javascript" > 
function disableBackButton() 
{ 
window.history.forward(); 
} 
setTimeout("disableBackButton()", 0); 
</script> 

Tenemos que ponerlo en la sección HTML de la página que se quiere prevenir usuario a visitar pulsando el botón de retroceso

Código completo de la página se parece a esto

<%@ Page Language="C#" AutoEventWireup="true" 
CodeFile="Default.aspx.cs" Inherits="_Default" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" > 
<head runat="server"> 
<title>Untitled Page</title> 
<script type = "text/javascript" > 
function disableBackButton() 
{ 
window.history.forward(); 
} 
setTimeout("disableBackButton()", 0); 
</script> 
</head> 
<body onload="disableBackButton()"> 
<form id="form1" runat="server"> 
<div> 
This is First page <br /> 
<br /> 
Go to Second page 
<br /> 
<br /> 
<asp:LinkButton ID="LinkButton1" runat="server" 
PostBackUrl="~/Default2.aspx">Go to Second Page 
</asp:LinkButton></div> 
</form> 
</body> 
</html> 

Si está usando Firefox entonces utilizar en lugar del proceso de carga

Si desea desactivar el botón de regreso utilizando código detrás de la página aspx, de lo que necesita para escribir código código C# a continuación se menciona detrás

protected override void OnPreRender(EventArgs e) 
{ 
base.OnPreRender(e); 
string strDisAbleBackButton; 
strDisAbleBackButton = "<script language="javascript">\n"; 
strDisAbleBackButton += "window.history.forward(1);\n"; 
strDisAbleBackButton += "\n</script>"; 
ClientScript.RegisterClientScriptBlock(this.Page.GetType(), "clientScript", strDisAbleBackButton); 
} 

También podemos lograr esto mediante la desactivación de la memoria caché del navegador o caché escribiendo esta línea de código, ya sea en el evento Page_Load o en caso Page_Init

protected void Page_Init(object Sender, EventArgs e) 
{ 
Response.Cache.SetCacheability(HttpCacheability.NoCache); 
Response.Cache.SetExpires(DateTime.Now.AddSeconds(-1)); 
Response.Cache.SetNoStore(); 
} 

al hacer esto, el usuario obtendrá el página ha caducado mensaje al golpear el botón atrás del navegador

Demo es:

enter image description here

1

no vi esta aquí, así que aquí está.

  1. Ponga un token único en el formulario.
  2. El botón enviar inicia una solicitud xmlhttp (ajax) al servidor para crear una variable de sesión denominada después del token con un valor almacenado de 1.
  3. La solicitud ajax envía el formulario después de recibir un cambio de estado positivo.
  4. El script de procesamiento de formularios busca la variable de sesión con el valor almacenado de 1.
  5. El script elimina la variable de sesión y procesa el formulario.

Si no se encuentra la variable de sesión, el formulario no se procesará. Como la variable se elimina tan pronto como se encuentra, el formulario solo se puede ejecutar presionando el botón de enviar. Actualizar y volver no enviará el formulario. Esto funcionará sin el uso de una redirección.

0

Este código funciona para no volver a la página actual mí ..

Aquí pongo un código que le ayuda, no contextual abierto y vuelva a cargar en el navegador solicita una página de salir o no ...

estoy tratando el ASK clic en el botón del navegador

jQuery(document).ready(function() { 

    document.onkeydown = fkey; 
    document.onkeypress = fkey 
    document.onkeyup = fkey; 

    var wasPressed = false; 

    function fkey(e){ 
     e = e || window.event; 
     //alert(e.keyCode); 
     if(wasPressed) return; 


     if (e.keyCode == 116 || e.keyCode == 8 || e.keyCode == 17) { 
        // alert("f5 pressed"); 
         window.onbeforeunload = null; 
         return true; 
       } 

    } 
window.onbeforeunload = function (event) { 
    var message = ''; // Type message here 

    if (typeof event == 'undefined') { 
     event = window.event; 
    } 
    if (event) { 
     event.returnValue = message; 
    } 

    return message; 
}; 

jQuery(function() { 

    jQuery("a").click(function() { 
     window.onbeforeunload = null; 
    }); 

    jQuery(".btn").click(function() { 
     window.onbeforeunload = null; 
    }); 

    //Disable part of page 
    $(document).on("contextmenu",function(e){ 
     return false; 
    }); 
});}); 

Gracias espalda,

Cuestiones relacionadas