你总是在发帖后重定向吗?如果是,你是如何做到的?

2022-05-26 00:00:00 form-submit jakarta-ee java

假设您正在提交一个表单,这会影响您的数据库(添加记录/删除记录/更新记录),您的请求如下所示:

POST/APPLICATE/ACTION=更新

现在,假设您已完成更新,因此您希望将用户带到主页。

Response.sendReDirect/app/action=home

这个效果非常好。用户在POST后被发送一个重定向,所以即使用户试图通过按F5来刷新页面,您也是好的。但是,如果您执行以下操作,则此操作将不起作用:

requestDispatcher.forward(/application/action=home)

假设在完成更新后必须显示不同类型的错误/成功消息,您很可能在POST之后进行转发。在这种情况下,如何避免发生两次更新操作?

我觉得很有趣的是,许多安全站点(银行)/支付网关倾向于通过在屏幕上放置文本来通知用户,例如"请不要按下后退/刷新按钮"。

没有更好的方法处理这件事了吗?除了要求用户不要按下这些按钮之外?当我最后一次检查的时候,有一个叫做‘垂直响应缓存’的东西。一个筛选器,它将标识您的请求在会话中的唯一性,并在请求重复时尝试发送缓存的响应。有没有更简单的方法来解决这个经典问题?

下面是我提到的垂直响应缓存解决方案的链接:http://www.fingo.info/en/articles/_1.html。然而,我不确定这是否真的有效。


解决方案

我的一个想法是在提交后的表单中嵌入一个唯一的ID(可能是一个随机字符串)作为隐藏的表单域。ID字符串可以作为"交易ID"放入数据库。现在,当您去更新数据库时,首先检查是否存在已提交交易ID的记录,如果有,则假定它是重复的,不要更改数据库。

当然,正如我所说的,这只是一个想法。我不知道在实践中实际使用的是什么方法。(我怀疑许多不那么重要的网站只是忽略了这个问题,希望他们的用户会很聪明……这是我见过的最失败的提议;-)

编辑:正如评论中指出的,在数据库中存储事务ID可能会占用大量空间,但如果这是一个问题,您可以在内存中保留在过去5分钟/1小时/1天/任何时间内处理的所有事务ID的缓存。这应该会奏效,除非你面对的是一个意志坚定的黑客...

相关文章