web-dev-qa-db-ja.com

window.onbeforeunload ajaxリクエストChrome

Ajaxを介してマシンのリモート制御を処理するWebページがあります。ユーザーがページから移動すると、マシンから自動的に切断されます。コードは次のとおりです。

window.onbeforeunload = function () {
  bas_disconnect_only();
}

切断機能は、HTTP GETリクエストをPHPサーバー側スクリプトに送信するだけで、実際の切断作業を行います:

function bas_disconnect_only () {
   var xhr = bas_send_request("req=10", function () {
   });
}

これはFireFoxでは問題なく機能します。ただし、Chromeでは、ajaxリクエストはまったく送信されません。許容できない回避策があります:コールバック関数にアラートを追加する:

function bas_disconnect_only () {
   var xhr = bas_send_request("req=10", function () {
     alert("You're been automatically disconnected.");
   });
}

アラートコールを追加すると、リクエストは正常に送信されます。しかし、ご覧のとおり、実際には回避策ではありません。

これがChromeで達成可能かどうか誰かに教えてもらえますか?私がやっていることは完全に合法的に見えます。

おかげで、

46
lang2

同じ問題を抱えていました。Chrome=は、window.unloadイベントでサーバーにAJAXリクエストを送信していませんでした。

リクエストが同期である場合にのみ機能させることができました。 Jqueryでこれを行うことができ、asyncプロパティをfalseに設定しました。

$(window).unload(function () {
   $.ajax({
     type: 'GET',
     async: false,
     url: 'SomeUrl.com?id=123'
   });
});

上記のコードはIE9、Chrome 19.0.1084.52 m、およびFirefox 12で機能しています。

40
Garry English

これは、Chromeの新しいバージョンに関連しています。

@Garry English said のように、ページasync中にonunloadリクエストを送信しても機能しません。ブラウザはリクエストを送信する前にスレッドを強制終了するからです。ただし、syncリクエストを送信しても機能します。

これはChromeのバージョン29までは正しいことでしたが、Chrome V 30では突然動作しなくなりました ここで述べたように

今日これを行う唯一の方法は、onbeforeunloadイベントを使用することであるようです ここで提案されているように

ただし、他のブラウザでは、onbeforeunloadイベントでAjaxリクエストを送信できません。そのため、アンロードとアンロード前の両方でアクションを実行し、既に実行されているかどうかを確認する必要があります。

このようなもの:

var _wasPageCleanedUp = false;
function pageCleanup()
{
    if (!_wasPageCleanedUp)
    {
        $.ajax({
            type: 'GET',
            async: false,
            url: 'SomeUrl.com/PageCleanup?id=123',
            success: function ()
            {
                _wasPageCleanedUp = true;
            }
        });
    }
}


$(window).on('beforeunload', function ()
{
    //this will work only for Chrome
    pageCleanup();
});

$(window).on("unload", function ()
{
    //this will work for other browsers
    pageCleanup();
});
67
Mohoch

この目的のために構築された Navigator.sendBeacon() メソッドをチェックアウトします。

MDNページには次のように記載されています。

Navigator.sendBeacon()メソッドを使用して、ユーザーエージェントからWebサーバーに小さなHTTPデータを非同期的に転送できます。

このメソッドは、ドキュメントのアンロード前に通常Webサーバーにデータを送信しようとする分析および診断コードのニーズに対応します。データをすぐに送信すると、データを収集する機会が失われる可能性があります。ただし、ドキュメントのアンロード中にデータが送信されたことを確認することは、開発者にとって伝統的に困難でした。

これは比較的新しいAPIであり、IEではまだサポートされていないようです。

19
Sparky

同期XMLHttpRequestは非推奨になりました( 同期および非同期要求 )。したがって、jQuery.ajax()async: falseオプションも廃止されました。

beforeunloadまたはunloadの間に同期リクエストを使用することは不可能(または非常に難しい)のようです( ChromeでのAjax同期リクエストの失敗 )。したがって、 sendBeacon を使用することをお勧めします。

単に:

window.addEventListener('beforeunload', function (event) {  // or 'unload'
    navigator.sendBeacon(URL, JSON.stringify({...}));

    // more safely (optional...?)
    var until = new Date().getTime() + 1000;
    while (new Date().getTime() < until);
});
0
GyuHyeon Choi

ユーザーがページを離れ、バックエンドにajaxリクエストを送信するケースを追跡する必要がありました。

var onLeavePage = function() {
    $.ajax({
        type: 'GET',
        async: false,
        data: {val1: 11, val2: 22},
        url: backend_url
    });
};

/**
 * Track user action: click url on page; close browser tab; click back/forward buttons in browser
 */
var is_mobile_or_tablet_device = some_function_to_detect();
var event_name_leave_page = (is_mobile_or_tablet_device) ? 'pagehide' : 'beforeunload';
window.addEventListener(event_name_leave_page, onLeavePage);

/**
 * Track user action when browser tab leave focus: click url on page with target="_blank"; user open new tab in browser; blur browser window etc.
 */
(/*@cc_on!@*/false) ?  // check for Internet Explorer
    document.onfocusout = onLeavePage :
    window.onblur = onLeavePage;

デスクトップブラウザで「ページ非表示」イベントが発生することに注意してください。ただし、ユーザーがブラウザの戻る/進むボタンをクリックしても発生しません(Mozilla Firefoxの最新バージョンでテスト)。

0
sNICkerssss

[〜#〜] ajax [〜#〜] requestでページからの離脱を検出する方法を探しています。使用するたびに動作し、MySQLで確認しました。これはコードです(Google Chromeで動作します):

    $(window).on("beforeunload", function () {
        $.ajax({
             type: 'POST',
             url: 'Cierre_unload.php',
             success: function () {
             }
        })
    })