如何防止"确认表单重新提交"对话框?

Mar*_*ose 22 javascript php jquery codeigniter

如何在提交后清除表单中的信息,以便在页面刷新后不显示此错误?

查看图片(来自chrome):

该对话框包含以下文字:

您要查找的页面使用
了您输入的信息.返回该
页面可能会导致您
重复执行任何操作.你想继续吗?

我希望这个对话框不会出现.

Tan*_*tta 34

这种方法对我很有效,我认为最简单的方法是在重新加载页面的 HTML 中使用这个 javascript 代码。

if ( window.history.replaceState ) {
  window.history.replaceState( null, null, window.location.href );
}
Run Code Online (Sandbox Code Playgroud)

  • 但有什么问题呢? (2认同)

Mik*_*ike 20

编辑:自从我最初发布这个答案已经有几年了,尽管我得到了一些赞成票,但我对之前的答案并不满意,所以我完全重做了.我希望这有帮助.


何时使用GETPOST:

摆脱此错误消息的一种方法是使用您的表单GET而不是POST.请记住,这并不总是一个合适的解决方案(请参阅下文).

如果您正在执行不想重复的操作,传输敏感信息或者表单包含文件上载或发送的所有数据长度超过~2000个字符,请始终使用POST.

何时使用的示例POST包括:

  • 登录表单
  • 联系表格
  • 提交付款表格
  • 从数据库添加,编辑或删除条目的东西
  • 图像上传(请注意,如果使用GET带有<input type="file">场,只有文件名会被发送到服务器,这时候99.73%,是不是你想要的.)
  • 包含许多字段的表单(如果使用GET,将创建一个长URL)

在任何这些情况下,您都不希望人们刷新页面并重新发送数据.如果您要发送敏感信息,使用GET不仅不合适,这将是一个安全问题(即使表单是由AJAX发送的),因为敏感项目(例如用户的密码)是在URL中发送的,因此会显示在服务器访问日志中.

使用GET基本上是其他任何东西.这意味着,当您不介意重复时,对于您可以提供直接链接的任何内容,当没有传输敏感信息时,当您非常确定您的URL长度不会失控时当您的表单没有任何文件上传时.

例子包括:

  • 在搜索引擎中执行搜索
  • 用于在网站上导航的导航表单
  • 使用随机数或一次性密码(例如电子邮件中的"取消订阅"链接)执行一次性操作.

在这些情况下,POST将是完全不合适的.想象一下,如果搜索引擎使用POST进行搜索.每次刷新页面时都会收到此消息,而您无法将结果URL复制并粘贴给人员,他们必须自己手动填写表单.

如果您使用POST:

对我来说,在大多数情况下,即使弹出"确认表单重新提交"对话框,也会显示存在设计缺陷.由于POST被用于执行破坏性操作的本质,Web设计人员应该通过意外(或有意)刷新页面来防止用户多次执行它们.许多用户甚至不知道这个对话的含义,因此只需点击"继续"即可.如果那是在"提交付款"请求之后怎么办?付款是否会再次发送?

所以你会怎么做?幸运的是,我们有Post/Redirect/Get设计模式.用户向服务器提交POST请求,服务器将用户的浏览器重定向到另一个页面,然后使用GET检索该页面.

这是一个使用PHP的简单示例:

if(!empty($_POST['username'] && !empty($_POST['password'])) {
    $user = new User;
    $user->login($_POST['username'], $_POST['password']);

    if ($user->isLoggedIn()) {
        header("Location: /admin/welcome.php");
        exit;
    }
    else {
        header("Location: /login.php?invalid_login");
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,在此示例中,即使密码不正确,我仍然会重定向回登录表单.要向用户显示无效的登录消息,请执行以下操作:

if (isset($_GET['invalid_login'])) {
    echo "Your username and password combination is invalid";
}
Run Code Online (Sandbox Code Playgroud)

  • 如果使用GET并刷新,则不会收到错误,但会重新提交数据.不推荐它. (4认同)
  • 如果服务器端验证失败,您如何重定向回相同的表单,以便显示无效值和错误消息?假设表单有许多无法放入 cookie 的字段。另外,假设您不想要服务器端状态。 (2认同)

Dou*_*ner 9

我遇到了这个问题并将这个 JavaScript 添加到我的页面底部,它似乎工作。解决方案似乎要简单得多。有什么缺点吗?

<script>
if ( window.history.replaceState ) {
  window.history.replaceState( null, null, window.location.href );
}
</script>
Run Code Online (Sandbox Code Playgroud)

  • 它与我完美配合。我希望没有缺点。 (3认同)

zat*_*ata 8

它与您的表单或其中的值无关.它被浏览器触发,以防止用户使用缓存数据重复相同的请求.如果您确实需要启用结果页面的刷新,则应该通过PHP(header('Location:result.php');)或您正在使用的其他服务器端语言重定向用户.元标记解决方案也应该用于禁用刷新时的重新发送.


小智 5

处理POST页面后,将用户重定向到同一页面.

http://test.com/test.php

header('Location: http://test.com/test.php');
Run Code Online (Sandbox Code Playgroud)

这将摆脱框,因为刷新页面将不会重新提交数据.

  • 这不是以无限循环的重定向结束吗? (2认同)