【问题标题】:Prevent Back button from showing POST confirmation alert防止返回按钮显示 POST 确认警报
【发布时间】:2010-10-14 04:54:46
【问题描述】:

我有一个向网页提供一长串参数的应用程序,因此我必须使用 POST 而不是 GET。问题是当页面被显示并且用户点击返回按钮时,Firefox 会显示一个警告:

要显示此页面,Firefox 必须发送重复之前执行的任何操作(例如搜索或订单确认)的信息。

由于应用程序的构建方式使得返回是一种非常常见的操作,这对最终用户来说确实很烦人。

基本上,我想按照这个页面的方式来做:

http://www.pikanya.net/testcache/

输入内容,提交,然后单击返回按钮。没有警告,它只是返回。

谷歌搜索我发现这可能是 Firefox 3 中的一个错误,但我想以某种方式得到这种行为,即使他们“修复”了它。

我想这可以通过一些 HTTP 标头来实现,但究竟是哪一个?

【问题讨论】:

  • 只是为了确保我知道这里发生了什么,你能粘贴警告的文本​​吗?
  • 您链接的页面不会消除警告。我仍然看到: 确认 要显示此页面,Firefox 必须发送将重复之前执行的任何操作(例如搜索或订单确认)的信息。 [重新发送] [取消]
  • 如果您使用 Firefox 3.0.6 或类似版本,则不会。您可能有一个浏览器已被“修复”。
  • 永久修复它的浏览器是 Opera。它根本没有这个对话框,它总是在不询问用户的情况下重新发送数据,迫使 Web 开发人员按照黄金法则做好他们的工作:-)
  • @Milan 您的测试应用程序可以在 Chrome 中运行,但当您按下前进按钮时,它会显示“确认重新提交表单”(!)

标签: php forms post http-headers


【解决方案1】:

在这里查看我的网络编程黄金法则:

Stop data inserting into a database twice

它说:“永远不要用正文响应 POST 请求。总是做这项工作,然后用 Location: 标头响应以重定向到更新的页面,以便浏览器使用 GET 请求它”

如果浏览器曾经询问用户重新发布,您的网络应用程序已损坏。用户不应该看到这个问题。

【讨论】:

  • 要生成网页,我需要提供大约 4k 的输入。我不能用 GET 做到这一点。没有“工作”要做,输出本身取决于给定的参数。我能想到的唯一想法是将 4k 的数据存储在 PHP 会话中并在 GET 请求中检索它,但如果用户有......
  • 亚马逊似乎没有遵循这条黄金法则
  • 米兰,只需将您的 4k 存储在临时文件中并重定向到将显示其中数据的页面。克里斯,大量的网站都是愚蠢的,包括流行的网站。这不是制作更多愚蠢网站的好借口:-)
  • 我会说你的“黄金法则”有点简单。如果 POST 不成功,就不应该有重定向。只有在请求之后才能处理。该概念也称为 PRG 或“发布后重定向”。
  • 这种方法的一个问题是使用303 See Other 响应重定向会阻止发送信息丰富的2xx 响应(例如201 Created202 Accepted)。 stackoverflow.com/questions/3383725/…
【解决方案2】:

一种解决方法是将 POST 重定向到重定向到 GET 的页面 - 请参阅 Post/Redirect/Get on wikipedia

假设您的 POST 是 4K 的表单数据。大概您的服务器对这些数据做了一些事情,而不是只显示一次然后将其丢弃,例如将其保存在数据库中。继续这样做,或者如果它是一个巨大的搜索表单,请在数据库中创建一个临时副本,几天后或在使用空间限制时基于 LRU 被清除。现在创建可以使用 GET 访问的数据表示。如果它是临时的,则为其生成一个 ID 并将其用作 URL;如果它是一组永久数据,它可能有一个 ID 或可用于 URL 的东西。在最坏的情况下,使用小 URL 之类的算法可以将大 URL 折叠成更小的 URL。重定向 POST 以获取数据的表示形式。


作为一个历史记录,这种技术是established practice in 1995

【讨论】:

  • 但是怎么做呢?输入数据超过4kB,页面输出取决于它。
  • 看起来我必须这样做,除非缓存有什么技巧。
  • 不要使用任何技巧,完全按照 Pete 建议的方式去做。我喜欢他的解决方案的地方在于它遵循简单的 REST 原则。
  • 这如何防止用户返回?他们从被重定向到的 303 GET 页面转到 back - 到他们发布到的页面。 Post/Redirect/Get 解决了用户按下F5 的问题,但是当用户按下back 按钮时并没有帮助。 (参见发布/重定向/获取维基百科en.wikipedia.org/wiki/Post/Redirect/Get
  • @Ian 假设您的浏览器获取页面 A,该页面上有一个 POST 表单。您的浏览器历史记录中有 GET A。您将表单发布到 B,并被重定向到 GET C。您的浏览器历史记录现在包含 GET A、GET C。它不应该记录 POST B,因为如果它获得 303 重定向,浏览器不应该在历史记录中记录该页面。尝试andypemberton.com/sandbox/prg 的沙盒并查看浏览器的历史记录,看看您是否获得了两页或三页。所以用户不会回到帖子的结果,而是回到表单。
【解决方案3】:

避免该警告/行为的一种方法是通过 AJAX 进行 POST,然后将用户单独发送到另一个页面(或不发送)。

【讨论】:

  • 是的,这是我的备用计划。但是,BACK 按钮不适用于 AJAX,所以在这种情况下我必须实现自己的“返回处理程序”,我想避免这种情况。
【解决方案4】:

我一直在使用 Session 变量来帮助解决这种情况。以下是我多年来一直使用的方法:

//If there's something in the POST, move it to the session and then redirect right back to where we are
if ($_POST) {
    $_SESSION['POST']=$_POST;
    redirect($_SERVER["REQUEST_URI"]);
}

//If there's something in the SESSION POST, move it back to the POST and clear the SESSION POST
if ($_SESSION['POST']) {
    $_POST=$_SESSION['POST'];
    unset($_SESSION['POST']);
}

从技术上讲,您甚至不需要将其放回名为 $_POST 的变量中。但它可以帮助我跟踪哪些数据来自哪里。

【讨论】:

    【解决方案5】:

    我有一个向网页提供一长串参数的应用程序,因此我必须使用 POST 而不是 GET。问题是当页面被显示并且用户点击返回按钮时,Firefox 会显示一个警告:

    你的推理是错误的。如果请求没有副作用,则应该是 GET。如果它有副作用,它应该是 POST。选择不应基于您需要传递的参数数量。

    【讨论】:

    • 没有副作用,但是参数是4kB。如果您不知道,GET 有 1024 个字节的限制。
    • 到底是什么参数占用了这么多空间?您能否进一步解释一下您的应用程序的上下文?
    • 假装是反向图片搜索,帖子数据是图片。
    • @ian_boyd 使用该用例,我将使用 POST 上传图像,然后将图像存储在服务器端的某个位置,并通过重定向到搜索页面进行响应,该页面引用一个键,由第一个请求生成。如果应用程序占用太多空间,您可以在一段时间后修剪图像存储。浏览器足够聪明,可以优雅地处理这个问题——离开重定向到页面后回击,不会提示重新发布。
    【解决方案6】:

    作为另一种解决方案,您可以完全停止使用重定向。

    您可以在没有POST 确认警报的情况下一次处理并呈现处理结果。您应该只操作浏览器历史记录对象:

    history.replaceState("", "", "/the/result/page")
    

    查看fullshort 答案

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      相关资源
      最近更新 更多