在浏览器中重新加载/刷新页面而不重新提交表单?

Posted

技术标签:

【中文标题】在浏览器中重新加载/刷新页面而不重新提交表单?【英文标题】:Reload/refresh page in browser without re-submitting form? 【发布时间】:2011-12-21 11:54:38 【问题描述】:

我在提交到同一页面的 php 页面上有一个表单。 我注意到,如果我重新加载/刷新页面,表单会重新提交。 如何以最简单的方式编写代码来避免这种情况?

【问题讨论】:

您可以尝试重定向到刷新页面。 en.wikipedia.org/wiki/Post/Redirect/Get 你不能......关键是用户输入可能是生成您当前所在的页面所必需的。我建议不要管这种行为,除非你有特定的理由来改变它。如果你这样做了,你可以按照 Blender 的建议去做,然后转到一个中间页面,或者在转到下一页之前通过 AJAX 发送你的数据。 也可以在隐藏输入中生成随机字符串,放入cookie(或会话)中,验证字符串是否对应cookie的值,第一次发送表单时销毁.因此,如果用户下次发送相同的数据,验证将失败,您知道表单已经发送。但它需要 cookie,所以如果您可以简单地重定向,这是更好的选择。 如果您想保持在同一页面上,可以使用 AJAX 异步提交表单。除此之外,大多数解决方案都是粗略的,实际上是一种 hack,而不是实际的解决方案。在刷新时提交 POST 数据是一种正常的浏览器行为,浏览器会保持这种状态是有原因的。 【参考方案1】:

这假设了很多事情,但也许是您正在寻找的:

if ($_POST)

    $success = false;

    /*
     * if all goes OK managing POST data make $success = true;
     * 
     */

    if ($success)
    
        // this will redirects to your original
        // form's page but using GET method
        // so re-submitting will be no possible
        header("location: $_SERVER['PHP_SELF']");
        exit;
    

【讨论】:

PHP_SELF 将删除任何 GET 参数。使用REQUEST_URI 保存它们。【参考方案2】:

一种可能性是,实现后重定向获取方法。

简单地说,一个 POST 请求永远不会传递给浏览器。相反,您执行所有必要的操作并将所需的信息存储在会话中,然后使用代码 303 进行重定向。

$page = 'show_result.php';
header('Location: '.$page, true, 303);
exit;

这样做,浏览器将显示“show_result.php”页面(GET 请求)而不是 POST 请求的页面。这也是添加到历史记录的页面,因此刷新和使用后退按钮将永远不会执行另一个 POST 请求。作为一个很好的副作用,您可以摆脱关于重新发送数据的浏览器警告,通常用户无法决定接下来要做什么。

我认为这种方法的最大问题是,您需要一个会话来存储错误消息,这意味着您必须依赖 cookie。如果不重定向显示错误,浏览器将显示有关重新发送数据的警告。

【讨论】:

Post-redirect-get 不需要会话,我不确定您所说的“POST 请求永远不会发送到浏览器”是什么意思 @j08691 - 每个 POST 请求都将通过重定向(代码 303)得到响应。浏览器收到这个答案并开始一个新的 GET 请求,它显示第一个请求的结果。当 POST 请求检测到无效的用户输入时,会话是必需的,并且下面的 GET 请求需要显示错误消息和最后的用户输入。【参考方案3】:

根据HTTP标准,你应该让浏览器在发送POST之后再做一个GET请求。 这是一个进行表单处理的草图示例:

<?  
if ($_SERVER['REQUEST_METHOD']=='POST')   

  $err = array();
  //performing all validations and raising corresponding errors
  if (empty($_POST['name']) $err[] = "Username field is required";  
  if (empty($_POST['text']) $err[] = "Comments field is required";  

  if (!$err)   
    //if no errors - saving data and redirect
    header("Location: ".$_SERVER['PHP_SELF']);
    exit;
    else 
    // all field values should be escaped according to html standard
    foreach ($_POST as $key => $val) 
      $form[$key] = htmlspecialchars($val);
    
 else 
  $form['name'] = $form['comments'] = '';  

include 'form.tpl.php';
?>  

【讨论】:

以上是关于在浏览器中重新加载/刷新页面而不重新提交表单?的主要内容,如果未能解决你的问题,请参考以下文章

在浏览器中刷新页面而不重新提交表单

提交按钮后如何重新加载谷歌recaptcha而不刷新页面? [复制]

jQuery提交表单而不重新加载页面

提交表单而不重新加载页面

如何在 Laravel 中提交 PUT 方法表单而不重新加载页面?

Blazor - 提交表单而不重新加载(没有 JS)