Pregunta

Decir, se envía un formulario, que afecta a la base de datos (añadir registros/ eliminación de ellos/ actualización de ellos) y esta es la forma en que su solicitud se parece a:

POST /aplicación/acción=actualizar

Ahora, dicen, que se realizan con su actualización, así que le gustaría llevar al usuario a la página de inicio.

Respuesta.sendRedirect /aplicación/acción=home

Esto funciona maravillosamente bien.El usuario se envía una redirección después de PUBLICAR, así que incluso si el usuario intenta actualizar la página presionando F5, que son buenos.Sin embargo, esto no funcionará si usted hizo esto:

requestDispatcher.adelante(/aplicaciones/acción=casa)

Dado que no es un escenario donde tienen que mostrar los diferentes tipos de error / mensajes de éxito después de que haya terminado con su actualización, lo más probable es hacer un avance después del POST.En tal escenario, ¿cómo se puede evitar acciones de actualización suceda dos veces?

Me parece bastante divertido que muchos de los sitios seguros (bancos) / pasarelas de pago tienden a informar al usuario mediante la colocación de texto en la pantalla, tales como "por Favor, no pulse back / actualización de los botones".

No hay mejor manera de manejar este?Otros que solicita el usuario no pulse estos botones?La última vez que me registré, no era algo que se llama 'Vertical Caché de Respuesta'.Un Filtro que identificar la singularidad de su solicitud en una sesión e intenta enviar una respuesta en caché si la solicitud es duplicar.Hay maneras más simples para la solución de este problema clásico?

Aquí hay un enlace a la vertical de la caché de respuesta de solución que se me estaba hablando: http://www.fingo.info/en/articles/_1.html.Estoy, sin Embargo, no estoy seguro de cuan bien esto realmente funciona.

¿Fue útil?

Solución

Un pensamiento que he tenido es la de insertar un IDENTIFICADOR único (probablemente una cadena aleatoria) como un campo de formulario oculto en el formulario que es estar en la POST-presentado.La cadena de ID se puede poner en la base de datos como un "ID de transacción".Ahora, cuando usted va a la actualización de la base de datos, comprueba en primer lugar si existe un registro con los datos presentados, el IDENTIFICADOR de transacción, y si es así, asumir que es un duplicado y no cambiar la base de datos.

Por supuesto, como he dicho, esto es sólo un pensamiento.No sé qué métodos se utilizan realmente en la práctica.(Sospecho que mucho de menos sitios críticos simplemente ignorar el problema y espero que sus usuarios será inteligente...una propuesta perdedora si he visto uno ;-)

EDITAR:como se señaló en los comentarios, almacenar los Identificadores de transacción en la base de datos puede tardar hasta un montón de espacio, pero si eso es un problema, se podría mantener una caché en memoria de todos los IDs de transacciones procesadas en los últimos 5 minutos/1 hora/1 día/lo que sea.Que debería de funcionar a menos que usted está en contra de un determinado hacker...

Otros consejos

Sí, yo creo que se debe redirigir después de un POST, con la excepción de las solicitudes de API. Sin hacer esto, no sólo usted tiene que preocuparse de conseguir POST duplicados cuando el usuario utiliza el botón de retroceso, pero el navegador también le dará al usuario diálogos molestos cuando tratan de utilizar el botón de retroceso.

response.sendRedirect funciona en la práctica, pero tecnically hablando, esto es enviar el código de respuesta HTTP incorrecto para esta finalidad. sendRedirect envía un 302, pero el código correcto que debe utilizarse para transformar un POST en un GET es 303. (la mayoría de los navegadores tratar un 302 como un 303 sin embargo, si lo consiguen en respuesta a un poste,)

En general desea que la redirección a enviar al usuario a cualquier punto de vista se mostrará el efecto de su cambio. Por ejemplo, si editar un widget, deben ser redirigidos a la vista de ese widget. Si eliminar un widget, deben ser redirigidos a la opinión de que el widget se habría aparecido en cuando existía (tal vez la lista de widgets).

A veces es bueno tener un mensaje de estado para impulsar aún más a casa el hecho de que se ha producido una acción. Una forma sencilla de hacer esto es tener un parámetro común a sus puntos de vista que, cuando se establece, se mostrará un mensaje de acción completado. por ejemplo:

/widget?id=12345&msg=Widget+modified.

Aquí, el parámetro "msg" contiene el mensaje "Widget modificado". La única desventaja de este enfoque es que puede ser posible que los sitios maliciosos para dar a sus usuarios mensajes confusos / engañosas. por ejemplo:

/account?msg=Foo+Corp.+hates+you.

Si usted está realmente preocupado por esto que podría incluir una firma que expira el mensaje como un parámetro adicional. Si la firma no es válida o ha caducado, simplemente no mostrar el mensaje.

La mejor solución para resolver el problema de mostrar mensajes de estado a los usuarios después de un POST a GET redirigir es el uso de las sesiones de usuario.

¿Cómo

Agregar atributos a la sesión de usuario con el valor como conjunto de mensajes a visualizar. para, por ejemplo.

userSession.put("success_messages", new HashSet<String>(){"Success", "Check your account balance"});
userSession.put("warning_messages", new HashSet<String>(){"Your account balance is low. Recharge immediately"});

Y tener un filtro que escanea la sesión de usuario para estos atributos particulares y da salida a los mensajes. El filtro debe eliminar los atributos después de leer una vez, ya que los mensajes de estado se muestran por lo general sólo una vez.

Me resulta bastante divertido que muchos sitios seguros (bancos) / pasarelas de pago tienden a informar al usuario mediante la colocación de texto en la pantalla, como "Por favor, no comprimir los botones / de actualización".

algunas personas encuentran su mejor "desactivar todo de vuelta, evento Refresh en estas páginas críticos"; No estoy seguro de si esto es bueno o no.

Pero su solución dirigida " caché respuesta verticales " suena bien

Es un poco obvio, pero no:

  • crear un objeto introducido en la sesión de usuario.
  • el valor es un Future Solicitud + java para el resultado
  • respondió de inmediato con una redirección del lado del cliente.
  • mientras que la redirección del lado del cliente se está manejando, tener un trabajo subproceso de trabajo en la producción de la respuesta.

Así que para cuando el navegador del cliente completa la redirección, obteniendo imágenes de la nueva página, etc ... Los resultados están a la espera para el usuario.

La alternativa es hacer que el usuario dolorosamente consciente de cuánto tiempo está tomando la base de datos.

Actualización de seguridad (el 2011 de enero 24):

La clave es vulnerable al ataque ya que es parte de la respuesta al cliente, por lo que

  1. Generar una clave aleatoria
  2. ID de sesión el uso del usuario como una sal de crear un SHA-1
  3. Tienda tanto la clave aleatoria y el SHA-1 en la base de datos con (,) como la clave principal. (Sin indexación por separado en el RANDOMKEY.
  4. utilizar tanto RANDOMKEY y el SHA-1 como la búsqueda db.
  5. No almacenar el identificador de sesión (evitar problemas de privacidad con la posibilidad de corollate muchas entradas para el mismo usuario)
  6. Expire los resultados después de 2-3 días. (Permite un trabajo por lotes todos los días para hacer la limpieza y evita crear problemas para las sesiones de los usuarios que son semi-larga duración)

Este método requiere que cualquier hacker a conocer tanto el identificador de sesión y la clave aleatoria.

Este enfoque puede parecer una exageración, sino un mecanismo de redirección endurecido puede ser utilizado para situaciones como el restablecimiento de contraseñas.

Si está trabajando con java script del lado del servidor y también utilizando puntales 2 a continuación, que se refieren este enlace que habla sobre el uso de token.

http://www.xinotes.org/notes/note/369/

Una ficha debe ser generado y mantenido en la sesión de la página inicial render, cuando la solicitud se presenta junto con el token, por primera vez, en la acción puntales ejecutar un hilo con el nombre de hilo como el ID de símbolo y ejecutar la lógica de lo el cliente ha solicitado para, cuando el cliente presente una vez más la misma petición, comprobar si el hilo sigue corriendo (thread.getcurrentthread (). interrumpida) si aún en marcha a continuación, enviar un cliente de redirección 503.

Por favor, mira el ExecuteAndWaitInterceptor de puntales 2code, la lógica de esta combinado con fichas le ayudará a salir rápido clic

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top