4

What is the best way to stop a form from being reprocessed when a user hits a Back button?

I'm following the Post/Redirect/Get pattern, so I don't have a problem if F5 is pushed, but the back button still provides the opportunity to resubmit the form. If this form is a credit card processing page, this is bad.

This question has been asked somewhat here, but the phrasing and answers were of poor quality and not specific to this problem exactly.

I have form.php which submits to itself. If there were no errors in input data upon submission, the user is redirected to form_thanks.php. Hitting back (and "Send" or "Resubmit") once resubmits form.php (BAD!) and then brings them back to form_thanks.php.

Please also include solutions that do not involve using Sessions, if possible.

4

6 回答 6

7

我会以不同的方式来做。使用随机字符串作为值设置隐藏输入,并在提交时将该随机字符串存储在会话中。设置一个简单的检查,看看他们是否已经发布了它,以及他们是否不接受输入。

于 2009-10-29T23:07:16.843 回答
2

这应该使用一次性令牌或nonce来完成。php/server 应该在一个隐藏的表单域中包含这个标记。

它应该存储所有最近令牌的列表,并且每次提交表单时,它应该检查令牌是否在最近的有效令牌列表中。

如果它不在列表中,则不要重新处理表单。
如果它在列表中,则处理表单并从列表中删除令牌。

令牌可以在会话中处理,或者只是一个没有会话的简单数据库表。令牌应该是特定于用户的。

这也是避免CSRF攻击的推荐方法。

于 2009-11-02T17:06:25.773 回答
1

迟到的答案,但可以通过使用基于 AJAX 的解决方案完全避免处理;在此处理方案中包含随机数不会有问题,但是通过使用异步查询,成功时重定向用户,不会通过刷新、按下或单击按钮以外的任何方式重复请求。

如果在请求期间发生某些事情,通过嵌入到请求的处理程序(无论是 PrototypeJS 或 jQuery 的高级还是低级别的你的handrolled function) 分别在请求完成和第一次触发时启用和禁用按钮的机制。

于 2009-11-17T20:58:25.753 回答
1

只是在这里大声思考。但是对于 post/redirect/get 的变化,最终获取实际上不是最终获取;)相反,它总是自动转发到真正的最终页面,因此如果用户点击后退按钮,他们会返回他们从哪里来的?

编辑:

好的,考虑到 OP 的评论,这是另一个想法。可以使表单提交的 URL 需要一个仅适用于一次用途的参数。该令牌将在提交表单之前生成(使用 MD5 或类似的),并且可以存储在数据库中(响应其他人的建议,您在不使用会话的情况下请求解决方案)。处理完表单后,此令牌将在数据库中标记为已被使用。这样当页面返回时使用相同的令牌,可以采取措施防止表单数据重新提交到后端。

于 2009-10-29T23:33:43.950 回答
0

我发现返回会将表单恢复到页面被重定向之前的状态,如果是这种情况,有一个隐藏的输入/变量或以值开头的东西说真,然后一旦提交表单,如果值为true,将其更改为false然后提交,否则返回false

于 2009-10-29T22:06:31.660 回答
-1

尝试这个 :

<SCRIPT type="text/javascript">
    window.history.forward();
</SCRIPT>
于 2012-10-02T06:16:00.007 回答