Navigator: sendBeacon() メソッド
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2018.
navigator.sendBeacon()
メソッドは、ウェブサーバーに非同期に少量のデータを HTTP POST リクエストで送ります。
これはウェブサーバーに分析データを送信するために使用するためのものであり、 XMLHttpRequest
を使用するような、分析を送信するための古い技術の問題のいくつかを避けています。
構文
sendBeacon(url)
sendBeacon(url, data)
引数
url
-
data を受け取る URL です。相対でも絶対でも可能です。
data
省略可-
送るデータを含む
ArrayBuffer
,TypedArray
,DataView
,Blob
, 文字列リテラルまたはオブジェクト、FormData
,URLSearchParams
のいずれかのオブジェクトです。
返値
sendBeacon()
メソッドが true
を返した場合は、ユーザーエージェントが転送のために data
をキューに入れることに成功したことを表します。それ以外の場合は false
を返します。
解説
このメソッドは、データをサーバーに送信する分析や診断コードのためのものです。
分析を送信する際の問題点として、サイトが多いのは、ユーザーがページの閲覧を完了したときに分析を送信したい場合です。例えば、ユーザーが別のページに移動したときなどです。このような場合、ブラウザーはページをアンロードしようとしている可能性があり、ブラウザーは非同期 XMLHttpRequest
リクエストを送信しないことを選ぶかもしれません。
伝統的には、これは以下のような回避方法を使用して、ある URL にデータを送信するまでページのアンロードを遅らせるよう位置づけられていました。
- データの送信をブロックする同期
XMLHttpRequest
の呼び出しで行う。 <img>
要素を作成し、そのsrc
をunload
ハンドラーの中で設定する。ほとんどのユーザーエージェントは画像を読み込むためにアンロードを遅延させる。- 数秒の何もしないループを作成する。
これらの方法はすべて、文書のアンロードをブロックするので、次への遷移が遅くなります。次のページがこれをやめさせる方法は存在しないので、前のページの問題であるにもかかわらず、次のページが遅いように見えます。
sendBeacon()
メソッドでは、ユーザーエージェントがその機会を持ったときに、アンロードや次のナビゲーションを遅らせることなく、非同期にデータを送信します。つまり、
- データは確実に送信されます。
- 非同期に送信されます。
- 次のページの読み込みには影響しません
データは HTTP POST リクエストで送信されます。
セッション終了時の分析の送信
ウェブサイトでは、ユーザーがページの閲覧を完了したときに、サーバーに分析結果や診断結果を送信したいことがよくあります。
これを行う最も信頼性の高い方法は、visibilitychange
イベントでデータを送信することです。
document.addEventListener("visibilitychange", function logData() {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
});
unload および beforeunload を避ける
これまで多くのウェブサイトは、セッションの終わりにアナリティクスを送信するために、 unload
または beforeunload
イベントを使用してきました。
しかし、これは非常に信頼性に欠けます。多くの場合、特にモバイルでは、ブラウザーは unload
、beforeunload
、pagehide
イベントを発行しません。例えば、次の例ではこれらのイベントは発行されません。
- ユーザーがページを読み込んで操作します。
- 完了語、タブを閉じずに別のアプリに切り替えます。
- その後、携帯電話のアプリマネージャーによってブラウザーアプリが閉じられました。
さらに、 unload
イベントは現行ブラウザーに実装されているバック/フォワードキャッシュ (bfcache) と互換性がありません。 Firefox のような一部のブラウザーは、アンロードハンドラーを格納したページを bfcache から除外することでこの非互換性を処理し、パフォーマンスを低下させています。他にも、 Safari や Android の Chrome などでは、ユーザーが同じタブで別のページに移動したときに unload
イベントを発生させないように処理しています。
Firefox はまた、ページが beforeunload
ハンドラーを格納している場合、bfcache からページを除外します。
pagehide をフォールバックとして使う
visibilitychange
を実装していないブラウザーに対応するには、 pagehide
イベントを使用します。
beforeunload
と unload
のように、このイベントは特にモバイルでは確実に発行されるわけではありません。しかし、 bfcache と互換性があります。
例
次の例では、 visibilitychange
イベントのハンドラーを指定しています。ハンドラーは sendBeacon()
を呼び出して分析を送信します。
document.addEventListener("visibilitychange", function logData() {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
});
仕様書
Specification |
---|
Beacon # sendbeacon-method |
ブラウザーの互換性
BCD tables only load in the browser
関連情報
visibilitychange
イベント- ビーコン API 概要ページ
- Don't lose user and app state, use Page Visibility は、
beforeunload
/unload
ではなく、visibilitychange
を使用する理由について詳しく説明しています。 - Page Lifecycle API は、ウェブアプリケーションでページのライフサイクル動作を処理するための最善の手法を提供します。
- PageLifecycle.js: ページのライフサイクル動作におけるクロスブラウザーでの不整合に対処する JavaScript ライブラリーです。
- Back/forward cache は、バック/フォワードキャッシュとは何か、そして様々なページライフサイクルイベントに対するその意味について説明します。