1

我正在维护一个网站,其中包含用户提交的一系列表单。每个表单都向服务器发送一个 HTTP POST,然后服务器将下一个表单呈现给浏览器。

即 index.html 包含 a <form action="form1.php" method="post">,然后 form1.php 呈现 a<form action="form2.php" method="post">等。

当我使用 iPhone 上的后退按钮从 form2.php 导航到 form1.php 时,请求是 form1.php 的HTTP GET,而不是使用 HTTP POST 重新提交。

这会间歇性地发生,但如果我最小化 safari 然后在我点击“返回”按钮之前再次重新打开它,则更可靠。

注意:无论我在 iPhone 上使用 chrome 还是 safari,都会发生这种情况。

我的期望是这些请求将使用 POST 重新提交。那是错的吗?

我在这里设置了一个小型复制器:http: //kong.idlemonkeys.net/~shaun/fi/

消息来源——对一些多余的东西感到抱歉,但他们应该传达这一点。

索引.html:

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    </head>
    <body>
        <form id="start-form" method="post" action="form1.php">
            <input type="hidden" name="foo" value="bar"/>
        </form>
        <div id="click-me" style="width: 200px; height: 200px; background-color: pink;">Click me</div>
    </body>
    <script type="text/javascript">
        $(document).ready(function() {
            $('#click-me').click(function() {
                $('#start-form').unbind('submit').submit();
            });
        });
    </script>
</html>

表格1.php:

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    </head>
    <body>
<?php if($_SERVER['REQUEST_METHOD'] !== 'POST') { ?>
<h2> you're doing it wrong </h2>
<?php } ?>
        <h1> This is form 1: <?php echo time(); ?></h1>
        <h1> You requested this page with: <?php echo $_SERVER['REQUEST_METHOD'] ?></h1>
        <form id="form1" method="post" action="form2.php">
            <button type="submit" value="submit" name="submit">Submit</button>
        </form>
    </body>
    <script type="text/javascript">
        $(document).ready(function() {
            $('#form1').submit(function () {
                alert('starting form submit');
            });
        });
    </script>
</html>

form2.php:

<html>
    <body>
        <h1> This is form 2: <?php echo time(); ?></h1>
        <h1> You requested this page with: <?php echo $_SERVER['REQUEST_METHOD'] ?></h1>
        <form method="post" action="form3.php">
            <button type="submit" value="submit" name="submit">Submit</button>
        </form>
    </body>
</html>

复制步骤:

  1. 在 iOS 上的 safari 或 chrome 中加载http://kong.idlemonkeys.net/~shaun/fi/
  2. 单击“单击我”按钮,将 POST 提交到 form1.php
  3. 单击“提交”按钮,将 POST 提交到 form2.php
  4. 最小化 safari(即转到主屏幕),然后将其重新启动。
  5. 点击“返回”按钮,注意 form1.php 现在通知您它是通过 HTTP GET 获取的

我已经能够使用wireshark确认事件的顺序

4

2 回答 2

2

我的期望是这些请求将使用 POST 重新提交。那是错的吗?

我相信这是错误的。POST 请求可能不是幂等的,即多次发布同一个帖子可能每次都会改变服务器的状态,这可能很危险。例如,浏览器无法知道您是否真的打算重新提交将您带到当前页面的表单,因此它不能假设再次发送 POST 是安全的。相反,它使用 GET,因为 GET 不会影响服务器的状态。

这个 StackOverflow 页面就是一个很好的例子。单击底部的“保存”按钮后,我的浏览器无疑会发出 POST 以将我的答案发送到服务器,然后显示包含我的新答案的结果网页。如果我点击后退按钮,我的浏览器是否应该再次发出 POST?这可能会导致添加我的答案的全新副本,这似乎根本不是正确的做法。另一方面,使用 GET 将安全地重新加载上一页,而无需重新发送我的答案。

于 2013-07-18T21:53:58.577 回答
1

在 POST 之后始终发送 HTTP 302 重定向可能是个好主意,以避免这种不一致的浏览器行为http://en.wikipedia.org/wiki/Post/Redirect/Get

于 2013-11-21T11:26:16.383 回答