2017-07-09 16 views
0

ユーザーがWebアプリケーションを終了すると、サーバーにデータを送信する必要があります。最善の方法はnavigator.sendBeaconですが、ブラウザのサポートは不良です。同期Ajaxリクエストを試しましたが、難しい方法ですが、サーバがレスポンスを返さずタイムアウトを設定する方法がない場合、タブはただ凍結されるということを学びました。だから私は、サーバーが十分に速く応答しない場合にタイムアウトを起こすことなく、すべてのブラウザで確実にデータを送信する必要があります。タイムアウトでアンロード時にサーバーにajaxデータを送信する

私はすでにこれを実装していますが、私はこの質問に答えるつもりですが、提案や解決策は大歓迎です。

答えて

0

Okですので、非同期XHRと2つのイベントbeforeunloadとunloadで実行できます。

私は1つのイベントでそれをやろうとしましたが、リクエストがループの前に送信されたとしても、ループが終了するまでリクエストは送信されません。

beforeunloadハンドラでは、非同期要求を送信して現在の時間を保存します。アンロードハンドラでは、十分な時間が経過していないか、サーバが応答した(readyStateをチェックしている)場合は、whileループを続行します。 ループが終了すると、ブラウザはウィンドウを自由にアンロードできます。

ここにコードがあります。また、ブラウザがサポートしている場合は、ビーコンを送信することもできました。

var unloadRequest = null, 
     requestStartTime = null, 
     isBeaconSupported = (navigator && typeof navigator.sendBeacon === 'function'); 

    window.onbeforeunload = function() { 

    if (isBeaconSupported) { 

      unloadRequest = new XMLHttpRequest(); 
      unloadRequest.withCredentials = true; 
      unloadRequest.open('POST', '/beacon', true); 
      unloadRequest.setRequestHeader("Content-Type", "text/plain"); 

      requestStartTime = performance.now(); 
      unloadRequest.send(JSON.stringify({ test: true, _sentBy: 'XMLHttpRequest' })); 

    } 

    //return true; 

}; 

window.onunload = function() { 

    if (isBeaconSupported) { 

    navigator.sendBeacon('/beacon', JSON.stringify({ test: true, _sentBy: 'beacon' })) 

    } else if (unloadRequest) { 

    //continue the loop if time is left and the request havent finished 
    while (requestStartTime + 3000 > performance.now() && unloadRequest.readyState !== XMLHttpRequest.DONE) { 

     //console.log(unloadRequest.readyState); 

     } 

     console.log('request finished or timed out') 
     console.log('it took: ' + (performance.now() - requestStartTime) + 'ms'); 

    }   

}; 
関連する問題