我有一个带有表单的 JSP 页面,您可以在其中填写某些详细信息。在提交表单时,我调用一个 servlet,然后更新数据库中的详细信息,然后我重定向到一个页面,我向用户显示一条确认消息。
我遇到的问题是,当用户点击返回时,他会再次进入表单页面,如果他点击提交按钮,就会在数据库中创建一条新记录。
将此视为类似于购物车的示例,在这种情况下,他会购买同一件商品两次。但这里唯一的问题是我无法在后端处理这个问题,即数据库永远不会知道正在进行的冗余操作。
我需要从客户端处理这个问题。有点奇怪,但我必须这样做。
基本上,当用户单击后退按钮时,我不希望他能够转到表单页面,而可能只是转到其他页面。
这是一个典型的HTML表单问题,您可以通过以下任一方法解决
1) 服务器端(页面过期):既然你提到了页面刷新并进入确认。您可以设置无缓存并将页面过期时间添加为 -1 到您拥有该表单的页面。
这样当用户按下后退按钮时,他会看到该页面已过期。他将被迫重新加载页面。这是我在大多数银行网站上看到的行为。
Response.Buffer = True
Response.ExpiresAbsolute = Now() - 1
Response.Expires = 0
Response.CacheControl = "no-cache"
2) 使用 turn Key 方法:当表单加载时,您可以在 session 内存中生成一个随 secret 钥,并将其作为隐藏值嵌入到页面中。
在表单提交期间,根据 session 中的值检查提交的隐藏键。如果存在,则将条目添加到数据库,否则您可以使用新 key 为用户(可能无意中这样做)重新加载页面。
在负载平衡或网络场中,考虑在数据库中针对当前用户保留交 key 。
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>