单击后退按钮后如何停止重新提交表单

时间:2016-05-29 14:26:18

标签: html forms jsp servlets webpage

我有一个JSP页面,其中包含填写某些详细信息的表单。在提交表单时,我调用一个servlet,然后在我重定向到页面后更新数据库中的详细信息,我向用户显示一条确认消息。

我遇到的问题是,当用户点击它时,他再次进入表单页面,如果他点击提交按钮,它会在数据库中创建一条新记录。

考虑这类似于购物车示例,在这种情况下,他会两次购买相同的商品。但这里唯一的问题是我无法在后端处理这个问题,即数据库永远不会知道正在进行冗余操作。 我需要从客户端处理这个问题。虽然很奇怪,但我必须这样做。

基本上,当用户点击后退按钮时,我不希望他能够转到表单页面,也可能只是某个其他页面。

4 个答案:

答案 0 :(得分:3)

这是一个典型的HTML表单问题,您可以通过以下任何一种方法解决它

1)服务器端(页面过期):由于您已经提到页面刷新并转到确认。您可以设置no-cache并将页面到期时间添加为您拥有该表单的页面的-1。 因此,当用户按下后退按钮时,他将看到该页面已过期。他将被迫新装入页面。这是我在大多数银行网站上看到的行为。

Response.Buffer = True
Response.ExpiresAbsolute = Now() - 1
Response.Expires = 0
Response.CacheControl = "no-cache"

2)使用turn key方法:当表单加载时,您可以在会话内存中生成随机密钥,并将其作为隐藏值嵌入页面中。 在表单提交期间,根据会话中的值检查提交的隐藏密钥。如果存在,则将条目添加到数据库,否则您可以使用新密钥为用户重新加载页面(可能是无意中完成的)。

在负载均衡或Web场中,请考虑针对当前用户在数据库中保留转向键。

3)客户端(不推荐):您可以通过从历史记录中删除页面来限制用户使用浏览器后退按钮。 (一个副作用是它将删除该浏览器选项卡/窗口的整个历史记录)

history.pushState(null, null, document.title);
window.addEventListener('popstate', function () {
    history.pushState(null, null, document.title);
});

如果您不支持不支持推送和弹出状态的旧浏览器,则可以使用以下代码段。

<script>
  function preventBack() {
    window.history.forward();
  }
  setTimeout("preventBack()", 0);
  window.onunload = function() {
    null
  };
</script>

答案 1 :(得分:1)

我认为以下流程是最好的:

  • 客户端将数据提交给服务器
  • Servlet处理它
  • 它返回HTTP 303重定向到客户端
  • 客户重定向到成功页面

在此流程之后,刷新,后退按钮将正常工作。

有关详细信息,请参阅Simple Post-Redirect-Get code example

答案 2 :(得分:1)

您可以使用php实现PRG模式(https://en.wikipedia.org/wiki/Post/Redirect/Get)。

基本上,在成功提交表单后,您会重定向到确认页面,通知用户他们的提交成功/接受/等。并设置一个变量,您可以在以后使用该变量来检查所述提交是否已提交。

当用户尝试重新加载所述页面或返回时,您可以检查变量并再次显示表单或根据提交是否已提交确认页面。

答案 3 :(得分:1)

在重定向到JSP页面之前,请使用来自控制器的响应发送这些标头,以便页面不存储在缓存中,浏览器将始终从服务器请求新页面。

response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0);

因此,每次返回该页面时,都会从服务器请求一个新页面,并显示清除的输入字段。

相关问题