我有一个名为'act'的隐藏参数,它应该传递其中一个值'load','save'按下提交按钮。
问题是在按下提交按钮后按下F5(刷新)按钮,因为网址已经包含'& act = save',因此f5上的prssing实际上再次传递(到cgi)'save'值(和即使我没有按下提交按钮,它也会再次执行保存操作。
问题是如何在按下重新打印按钮时阻止发送'& act = save'?
由于
谢谢大家,但提交按钮是一个“保存”按钮 - 意味着我希望让用户无法保存,因此请不要离开页面。 由于这个原因,我不认为会话可能有助于区分第二次保存或第一次刷新。
答案 0 :(得分:6)
这里的核心问题是,当您应该使用POST时,您正在使用GET。 The HTTP specification says:
特别是,已经确定了GET和HEAD方法不具有采取除检索之外的动作的重要性的约定。
如果您使用的是POST,那么浏览器至少会警告您重新提交表单。
为避免这种情况,请使用POST-Redirect-GET pattern。
答案 1 :(得分:2)
您无法阻止用户按 F5 或阻止重新加载页面重新提交表单 - 即使在表单中使用POST
方法也允许用户重新发送数据。
要克服这两个常见问题:
使用Session变量,在第一个表单提交时设置它然后检查它 - 如果存在,则表示已经提交的表单,所以只需忽略它或发布自定义消息。
成功提交后,将用户重定向到其他页面 - 这样点击 F5 将重新加载该新页面,并且不会重新发送数据。
答案 2 :(得分:0)
比已经提供的解决方案更复杂的解决方案是每次生成带有表单的页面时创建操作令牌。此操作令牌存储在服务器上,也会发送到客户端。当客户端提交表单时,它包含操作令牌。当服务器收到表单提交时,它会根据存储在该用户会话中的令牌或令牌来检查操作令牌。如果它与未过期的令牌匹配,那么它允许表单处理继续并在会话中使令牌过期。
这样可以防止多次提交表单,并且还有一个附带的好处,即如果实施得当,它可以帮助缓解跨站点请求伪造。