我有一个JSP页面,其中包含填写某些详细信息的表单。在提交表单时,我调用一个servlet,然后在我重定向到页面后更新数据库中的详细信息,我向用户显示一条确认消息。
我遇到的问题是,当用户点击它时,他再次进入表单页面,如果他点击提交按钮,它会在数据库中创建一条新记录。
考虑这类似于购物车示例,在这种情况下,他会两次购买相同的商品。但这里唯一的问题是我无法在后端处理这个问题,即数据库永远不会知道正在进行冗余操作。 我需要从客户端处理这个问题。虽然很奇怪,但我必须这样做。
基本上,当用户点击后退按钮时,我不希望他能够转到表单页面,也可能只是某个其他页面。
答案 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)
我认为以下流程是最好的:
在此流程之后,刷新,后退按钮将正常工作。
有关详细信息,请参阅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);
因此,每次返回该页面时,都会从服务器请求一个新页面,并显示清除的输入字段。