やりたかったこと
自分がしたかったととしては、サイト内でユーザーが操作した情報(クリック・どの画像を見た)を取得して、ページ遷移するときにブラウザ側からデータを送信して、情報を保存したかった。
行ったこと
まず、ブラウザ上でjavascript(具体的にはVue.js)を使って、変数にユーザーの操作情報を保存しました。
それをページ遷移するときに下記のメソッドを実行してsendbeacon()メソッドを使って送信しました。
function sendBeacon(data, url) {
const formData = new FormData();
Object.keys(data).forEach((key) => {
if (data[key] !== undefined && data[key] !== "" && data[key] !== null) {
formData.append(key, data[key]);
}
});
return navigator.sendBeacon(`${url}`, formData);
}
発生した問題
Chromeでは問題なく送信がされて、DBにデータが保存されているのが確認できたが、safariで試すとDBにデータが保存されていませんでした。
原因について
原因について調べてみると可能性としてSafariではsendbeacon()を使ったページ遷移じのリクエスト通信には以下のような制限があるとわかりました。
ページ遷移時の制限
Safariでは、ページ遷移時にsendBeacon()メソッドが呼び出された場合、そのリクエストがキャンセルされることある。
これは、Safariがページ遷移時にリソースを節約するために行う最適化の一部のようです。
解決策
解決策としてはsendbeacon()メソッドではなくfetch()メソッドを使用してデータの送信を行うようにしました。
fetch()メソッドには「keepalive」というオプションがあります。
「keepalive」オプションは、ページ終了後のリクエストを許可するのに使用されるもので、trueを設定することで、ページが終了してもリクエストが送信されます。
参照記事:https://developer.mozilla.org/ja/docs/Web/API/fetch#keepalive
function sendFetch(data, url) {
const formData = new FormData();
Object.keys(data).forEach((key) => {
if (data[key] !== undefined && data[key] !== "" && data[key] !== null) {
formData.append(key, data[key]);
}
});
// fetchメソッドを使用してデータを送信
return fetch(`${url}`, {
method: "POST",
body: formData,
keepalive: true,
})
}