12

ajax リクエストが送信されるまでブラウザでページを開いたままにしておきたいと思います。これは私がそれがどのように見えるかを想像するものです

var requestsPending = 0;

window.onbeforeunload = function() {
    showPleaseWaitMessage();
    while(requestsPending > 0);
}

// called before making ajax request, atomic somehow
function ajaxStarted() {
    requestsPending++;
}
// called when ajax finishes, also atomic
function ajaxFinished() {
    requestsPending--;
}

残念ながら、JS はマルチスレッドに対応していません。私の理解では、コールバック (ajaxFinished) は決して実行されません。これは、ブラウザが while ループの実行が終了するまで待機しようとするため、永久にループするためです。

これを行う正しい方法は何ですか?JS に to-do リストの次のことを評価させてから、while ループに戻るように強制する方法はありますか? または、ajax 呼び出しで「結合」する構文はありますか? ajaxにDWRを使用しています。

ありがとう -マックス

4

2 に答える 2

13

編集以下のコメントに基づいて、修正された回答:

以前に開始されたリクエストが完了するまでブロックしたい場合は、次のようにできます。

window.onbeforeunload = function(event) {
    var s;
    event = event || window.event;
    if (requestsPending > 0) {
        s = "Your most recent changes are still being saved. " +
            "If you close the window now, they may not be saved.";
        event.returnValue = s;
        return s;
    }
}

ブラウザは、ユーザーがページを離れるか、ページにとどまるかを尋ねるプロンプトを表示し、ユーザーが制御できるようにします。ユーザーがページにとどまり、プロンプトが表示されている間にリクエストが完了した場合、次にユーザーがページを閉じようとすると、確認せずにページを閉じることができます。

最新のブラウザーでは、メッセージは表示されないことに注意してください。代わりに、ブラウザは一般的なメッセージを使用します。したがって、最新のブラウザーでは、空白以外の文字列を返すだけで十分です。それでも、ユーザーがまだ表示する古いブラウザを使用している場合に備えて、(上記のような) 有用な文字列を返したい場合があります。

閉じるイベントをキャンセルするかどうかをユーザーに尋ねる方法については、こちらこちらをご覧ください。


古い答え:

理想的には、可能であれば、これを避ける必要があります。:-)

避けられない場合は、Ajax リクエストをsynchronousonbeforeunloadにして、完了するまでプロセスをブロックすることができます。DWRについてはわかりませんが、リクエストが同期かどうかを制御するフラグがあると思います。生の XmlHTTPRequest API では、これは次の 3 番目のパラメーターopenです。

req.open('GET', 'http://www.mozilla.org/', false);
                                            ^ false = synchronous

ほとんどのライブラリには同等のものがあります。たとえば、Prototypeではasynchronous: false、オプションのフラグです。

しかし、繰り返しますが、ページのアンロードの一部として Ajax リクエストを発生させないようにすることができれば、そうします。リクエストがセットアップされ、送信され、完了するまでにかなりの遅延が発生します。これで閉じようとしているものが何であれ、サーバーにタイムアウトを使用させて閉じる方がはるかに優れています。(かなり短いタイムアウトになる可能性があります。ページが開いている間、非同期の Ajax リクエストをページで定期的に使用することで、セッションを存続させることができます。たとえば、1 分に 1 回、2 分後にタイムアウトします。)

于 2010-06-04T00:44:53.610 に答える
4

つまり、これを行うことはできません (また、行うべきではありません)。ユーザーがブラウザーを閉じると、ブラウザーは閉じられます...unload終了が保証されるスタイル イベントはなく、レイテンシを伴う AJAX を実行しているものは、終了する可能性が低くなります。

別の時点でイベントの発生を検討するか、アプローチを完全に変更する必要がありますが、イベントで AJAX 呼び出しを行うことは、せいぜいunload信頼性が低くなります。

上記のすべきでない部分の補足として、次のように考えてください。通常、特定のウィンドウでいくつのタブを開いていますか? 私は通常、それぞれ 5 ~ 12 個のタブを持つ 4 ~ 6 個のクロム ウィンドウを開いています。私はそれをユーザーとしてやりたくないので、開発者としてやろうとはしません。もちろん、これは単なる意見ですが、検討の余地があります。

于 2010-06-04T00:43:48.150 に答える