1

ユーザーが送信する一連のフォームを持つ Web サイトを維持しています。各フォームはサーバーに対して HTTP POST を実行し、サーバーは次のフォームをブラウザーにレンダリングします。

つまり、index.html には が含まれ、<form action="form1.php" method="post">form1.php は<form action="form2.php" method="post">などをレンダリングします。

たとえば、iPhone で form2.php から form1.php に戻るボタンを使用して移動すると、リクエストはHTTP POST を使用した再送信ではなく、form1.phpのHTTP GETになります。

これは断続的に発生しますが、「戻る」ボタンを押す前にサファリを最小化してから再度開くと、より確実に発生します。

: これは、iPhone でクロムまたはサファリを使用しているかどうかに関係なく発生します。

私の期待は、これらのリクエストが POST を使用して再送信されることでした。それは間違っていますか?

私はここに小さな再現をセットアップしました: http://kong.idlemonkeys.net/~shaun/fi/

情報源 -- 余計なことを言って申し訳ありませんが、ポイントを伝える必要があります。

index.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>

form1.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 を発行して回答をサーバーに送信し、新しい回答を含む結果の Web ページを表示します。戻るボタンを押した場合、ブラウザは再び POST を発行する必要がありますか? その結果、私の回答のまったく新しいコピーが追加される可能性がありますが、これは正しいことではないようです。一方、GET を使用すると、回答を再送信せずに前のページを安全にリロードできます。

于 2013-07-18T21:53:58.577 に答える