JavaScriptで次のようなことをやりたい。
- サーバーからオブジェクト(状態)を取得する。認証付き
- ページ遷移時、オブジェクトは自動的にサーバーに投げられ保存される
コードで表すと
const state = await autosave_state(url, id, password)
実装コード
JavaScript側。IE非対応
beforeunload
イベント時にnavigator.sendBeacon()
を実行するのが正着
async function autosave_state(url, id, password){
const r = new FormData()
r.append('r', JSON.stringify({id, password}))
const http = await fetch(url, {method:'POST', mode:'cors', credentials:'include', body:r})
const state = await http.json()
window.addEventListener('beforeunload', function(){
const w = new FormData()
w.append('w', JSON.stringify({id, password, state}))
navigator.sendBeacon(url, w)
})
return state
}
サーバ側。サンプルコードをPHPで。
<?php
if(isset($_POST['r'])){ //取得動作
$r = json_decode($_POST['r']);
// 認証。$r->id、$r->password を確認する
// 取得。$state に送信したいオブジェクト
header('Content-Type: application/json');
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
print json_encode($state);
}
else if(isset($_POST['w'])){ //保存動作
$w = json_decode($_POST['w']);
// 認証。$w->id、$w->password を確認する
// 保存。$w->state を保存する
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
http_response_code(204);
}
sendBeacon 以外の方法
fetchのオプションでkeepalive:true
とすると、sendBeaconと同等の機能になるらしい。送信可能な容量は64KB。
https://ja.javascript.info/fetch-api