3

ブラウザ(IE、Mozilla、Chrome)からJavaアプリへのjQueryAJAXjsonp非同期リクエストを作成しています。4分以内に応答がない場合、リクエストはすべてのブラウザでタイムアウトになります。タイムアウトの場合、IEは自動的に新しいリクエストを起動し、Mozillaは単にそのリクエストを終了します。リクエストをタイムアウトさせたくない(つまり、サーバーからの応答がなくなるまで待つ必要があります)jQuery AJAX JSONPリクエストのタイムアウトを無効にする方法はありますか?

一部のサイトでは、この回避策としてタイムアウト値を大きく設定しすぎることを提案していますが、これは、長期間経過してもタイムアウトになるため、使用したくありません。

4

3 に答える 3

2

とにかく、リクエストをタイムアウトさせてから、それを適切に処理できるとは思いません。正確に何が起こるかはブラウザ次第であることにすでに気付いているので、ほとんど制御できません。

ただし、解決策はかなり単純だと思います。リクエストをタイムアウトさせないでください。

Java アプリケーションの jsonp コールバック ハンドラを変更して、タイムアウト期間が過ぎたこと、およびリクエストを再度実行する必要があることをクライアントに通知することは、ほとんど手間をかけずに行うことができます。

私が言いたいことを正確に示すために、完全に機能する実際の例を作成しました。

この例は nodejs にありますが、サーバー側の実装は最小限に抑える必要があると思います。それは、クライアント側のコードが何をするかということです。

デモ:
http://jsonp-timeout.herokuapp.com/

ソース:
https://github.com/helmus/jsonp-timeout/blob/master/public/index.html

これは実際に関連するすべてのコードです。
基本的には、jsonp 呼び出しを関数内に配置して、再利用できるようにします。その後、ハンドラーが応答を受信した場合、"timeout"サーバーが他のアクションが関連していると判断するまで、ハンドラーは簡単に要求をやり直すことができます。

$(function(){
    $("#call").on("click", function(){
        var makeJsonpCall = function(){
            return $.ajax({
                url: "rpc.js",
                dataType: "jsonp"
            });
        };
        var handler = function(data){
            if (data === "timeout") {
                console.log("a timeout occured, forwarding your request");
                makeJsonpCall().done(handler);
                return;
            }else{
                console.log("request completed");
            }
        };
        makeJsonpCall().done(handler);
    });
});

このアプローチは確かに十分に堅牢であり、インターフェースを最小限の変更で維持できると思います。また、エンドポイントがサポートしている場合、クロスドメイン jsonp でももちろん動作します。
タイムアウト期間を 2 または 3 分 (サーバー側) に変更できますが、それよりも長くすることはありません。

于 2013-07-23T20:20:31.027 に答える
2

間違いなく Websockets ほど高度ではない別のオプションは、結果のアドレスをポーリングすることです。次のシナリオを検討してください。

画面にレポートを表示する必要がありますが、読み込みに時間がかかります。最初のリクエストをサーバーに送信できます。次に、サーバーはレポートを開始し、クライアントが結果をポーリングできる uri を返します。次に、クライアントはその uri をポーリングし、レポートが完了するまで (おそらく) 404 を取得します。レポートが完了すると、URI でアクセスできるようになり、ブラウザに表示できます。

ブラウザのタイムアウトや派手な JavaScript の迂回に抵抗しないことをお勧めします。時々動作するようになったとしても、人々はさまざまなブラウザーを使用しているため (最近ではモバイルでも)、エラーが発生しやすくなります。堅牢なソリューションを持つことは、物事をシンプルで保守しやすくするのに役立ちます。

@BalusC が述べたように、Web ソケットはこの種のものに最適です。パラダイムを少し変えて、時間に余裕があるなら、それはすばらしい解決策です。ウェブは間違いなくこのようになります。ただし、時間に追われている場合は、短期的には最善の解決策ではない可能性があります。

于 2013-07-23T13:20:04.533 に答える
1

私のやり方には、サーバー、クライアント、およびデータベースのセットアップが含まれます。

タイム アペンダーを使用して一意のハッシュ キーを格納するデータベースを作成します。それがクライアントリクエストキーです。データごとに探しているもののデータブロック、またはそのリクエストが完了したかどうかを知るためのブール値のいずれかが含まれています。

サーバー側: クライアントがこのリクエストを呼び出すと、その一意のキーを保存し、イベントの処理を開始します。プロセスが完了するまで、2 番目の列は false になります。完了すると、そのテーブルを true に反転します。

クライアント: ajax リクエストでサーバーに ping を実行し、そのリクエストの成功呼び出しでタイムアウトを使用し、データベースをチェックしてプロセスが完了したかどうかを確認する一連のリクエストを作成します。内部リクエストでは、タイムアウトは 4 分に 1 回など、好きなようにする必要がありますが、成功を返すと目的のデータが得られ、タイマーを削除する必要があります。true を返さない場合は、エラー関数が呼び出され、何もしません。

このダブル リクエスト システムにより、リクエストを発行し、時間の経過とともに監視することができます。それが完了すると、探しているものが得られます。このシステムは 1 つのリクエストを起動しているため、タイムアウトを削除し、時間の経過とともにチェックアップ リクエストを起動します。

これは、タイムアウトがないように解決する方法です。データのフェッチなどを保留しているハング プロセスはありません。

編集:データベーステーブルからその行を削除するクリーンアップスクリプトと、スペースを無駄にしないことに関連する他のすべてのものを実行する必要があります。

于 2013-07-25T20:23:01.613 に答える