26

私が持っている質問は、おそらくブラウザー関連の質問だと思いますが、Web アプリケーションの構築に挑戦するときに答えを見つけたいと思う非常に基本的な質問です。

私のクライアント側のコードでは、$.ajax呼び出しを行っています。この投稿への返信には時間がかかる場合があります。私が見ているのは、一定の時間が経過した後、リクエストが再度送信されていることです。

私は$.ajaxそれをもう一度送信する私の呼び出しだと思っていましたが、サーバーで POST 要求を何度見ても、beforeSendコールバックが呼び出されたのは 1 回しか表示されません。私のコードが複数回送信していないと確信しているので、ブラウザが再試行していると思いますか?

Wireshark を実行したときにサーバーがリクエストを複数回受け取っていることはわかっており、投稿リクエストを複数回確認できます。だから私の仮定は、これはHTTPと関係があるのでしょうか? つまり、応答が一定時間内に受信されない場合、要求は再送信されますか?

以下は私の呼び出しのサンプルです。

$.ajax({
                    async: false,
                    type: 'POST',
                    url: '<%= url_for('importDevice') %>',
                    data: { device: val },
                    retryLimit: 0,
                    //callback
                    success: function(data) {
                    alert('calling import');
                    if ( data == 'nomaster')
                    {
                            // Display a warning  toast, with a title
                            toastr.warning('You must set the Master Key first!', 'Warning');
                            $.ismasterset = false;
                            //reset the form contents after added
                    } else
                    {
                            $("div#content").html(data);
                    }
                    },
                     beforeSend: function(){
                    alert('in before send');
                    }
            });

これはすべての関連コードです。「retryLimit」は使用されていません。コードから削除していないだけで、挿入する前に問題がありました。

クライアントとサーバーからの出力で編集。

OK、「Firefox 用のライブ HTTP ヘッダー」をインストールしました。

「ジェネレーター」タブに、単一の呼び出しが表示されます

'#request# POST http://testhost/importdevice' 

「ヘッダー」セクションに が表示されませんPOSTが、応答がないためでしょうか?

私のWebサーバーでは、約22秒離れた2つの呼び出しが表示されます。

[Sun Jan 13 03:08:45 2013] [debug] POST /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0).

[Sun Jan 13 03:09:07 2013] [debug] POST /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0).

これらの同じ呼び出しもwiresharkで見ることができます...

これが、TCP ハンドシェイクと再送信と同様の方法で、応答が返されない場合に要求を再送信しようとするのが通常の動作であるかどうかを尋ねていた理由ですSYN

新しいアップデート

私のAjax呼び出しとは何の関係もないようです。単純な HREF でボタンを作成するとします。

すなわち

<a href="/importdevice?device=serverA" class="btn btn-success">TestDirect</a>

次に、「Live HTTP headers」出力で... 1 つのインスタンスのみを取得します。

#request# GET http://172.16.118.15/importdevice?device=serverA

しかし、サーバーログでもう一度取得します。

[Sun Jan 13 03:20:25 2013] [debug] GET /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS  X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0).
[Sun Jan 13 03:20:48 2013] [debug] GET /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0).

そして、サーバー上のwiresharkでも2回表示されます...そして、予想どおり、サーバーコードも2回呼び出されます...これは本当に混乱します。

4

2 に答える 2

28

何が起こっているかを説明するこのブログ投稿をチェックしてください: http://geek.starbean.net/?p=393

HTTP/1.1 RFC 8.2.4によると:

HTTP/1.1 クライアントがリクエスト本文を含むが、「100-continue」期待値を持つ Expect リクエスト ヘッダー フィールドを含まないリクエストを送信する場合、およびクライアントが HTTP/1.1 オリジン サーバーに直接接続されていない場合、およびクライアントがサーバーからステータスを受信する前に接続が閉じていることを確認した場合、クライアントはリクエストを再試行する必要があります。

これらの余分な要求を許容するように Web アプリを設計してください。また、データベースへの書き込みなど、ajax リクエストで何かを 1 回だけ実行する場合は、リクエストを冪等に設計する必要があります。参照:べき等操作とは

また、これは GET 操作と POST 操作の違いを強調しています: http://www.cs.tut.fi/~jkorpela/forms/methods.html

一般的な設計方法として:
-GET 操作はべき等として設計する必要があります
-POST 操作はデータベースへの書き込みなどに使用する必要があります。

于 2013-01-15T19:34:44.540 に答える
0

リクエストが非同期でない場合、なぜコールバックを設定するのですか?

同期プロセスが必要な場合は、呼び出しの前にbeforeSendコードを配置し、呼び出しの直後に成功コールバックを配置します。

非同期アプローチが必要な場合は、asyncを設定します:true

また、このコード行は間違っています。

url: '<%= url_for('importDevice') %>',

引用符を見てください:

url: '<%= url_for("importDevice") %>',

たぶん、それらの提案は問題を解決しないでしょうが、あなたを正しい方向に向けるでしょう。問題は、投稿されたコード以外の場所にある可能性があります...

あなたの質問に戻ります:それはブラウザでしょうか?私は思いませんが、誰がそこに何があるかを知っています!! ...ブラウザは何ですか?別のもので試しましたか?

Firefoxを試して、Live httpHeadersプラグインを使用することをお勧めします(セットアップと使用は非常に簡単です)。サーバー側から何が入ってくるのかではなく、クライアント側から何が出ているのかがわかります。

于 2013-01-13T10:40:41.700 に答える