あるタブでユーザーがログインし、別のタブを開いてそこからログアウトしたと想像してください。 最初はログインしているようですが、彼がそこで何かをすると、エラーが発生します。 少なくとも、彼がログアウトしていて、再び入力する必要があるというダイアログを彼に見せることは素晴らしいでしょう。
WebSocket APIを使用することは可能ですが、あまりにも複雑です。 私は他のソリューションを探し始めました。 1つは、CookieとlocalStorageを保存し、定期的にチェックすることです。 しかし、これはかなり役に立たないタスクでプロセッサに負担をかけることになります-結局、出力はまったく発生しなかったかもしれません。 長いポーリング (長い要求)、サーバー送信イベント、またはWebSocketのオプションの方がより快適です。 驚いたことに、答えはlocalStorageエリアにあることが判明しました!
localStorageがイベントを起動することを知っていますか? より正確には、何かがリポジトリから追加、変更、または削除されたときにイベントが発生します。 つまり、任意のタブでlocalStorageをタッチすると、他の誰もがそれについて知ることができます。 ウィンドウオブジェクトのイベントをリッスンするだけです。
window.addEventListener('storage', function (event) { console.log(event.key, event.newValue); });
イベントオブジェクトには次のプロパティがあります。
key-localStorageでタッチされたキー
newValue-割り当てられた新しい値
oldValue-変更前の値
url-変更が発生したページのURL
したがって、localStorageの値を設定するだけで、タブ間の通信を確立できます。 次の例を想像してください(擬似コード):
var loggedOn; // TODO: logonChanged(); window.addEventListener('storage', updateLogon); window.addEventListener('focus', checkLogon); function getUsernameOrNull () { // TODO: , } function logonChanged () { var uname = getUsernameOrNull(); loggedOn = uname; localStorage.setItem('logged-on', uname); } function updateLogon (event) { if (event.key === 'logged-on') { loggedOn = event.newValue; } } function checkLogon () { var uname = getUsernameOrNull(); if (uname !== loggedOn) { location.reload(); } }
ユーザーがいずれかのタブに移動し、もう一方のタブに移動すると、ページがリロードされ、サーバーロジックはそれをどこかにリダイレクトします。 この場合、ユーザーがこのタブを選択した場合にのみチェックが行われます。 突然外出してタブの1つにログインした場合、他の全員にログアウトする必要はありません。
これは別の方法で動作するはずです-ユーザーが1つのタブにログインし、別のタブにログインした場合、2番目のタブに切り替えると、ページがリロードされ、そこにもログインします。 喜び。
APIはよりシンプルです
localStorage APIは最も単純なインターフェースの1つです。 ただし、SafariやQuotaExceededErrorなどの機能もあり、JSONや古いブラウザーはサポートされていません。
これを行うために、ローカルストレージに簡素化されたAPIを提供するモジュールを作成し、これらの機能からユーザーを救い、突然localStorageがサポートされない場合にメモリを操作し、イベントを操作しやすくしました。 指定したキーのこれらのイベントのリスナーを登録および削除できます。
local-storageを操作するスキームを次に示します 。
ls(key、value?)はキー値を取得または設定します
ls.get(key)はキー値を取得します
ls.set(key、value)は値を設定します
ls.remove(key)はキーを削除します
ls.on(key、fn(value、old、url))は他のタブの変更をリッスンし、fnを実行します
ls.off(key、fn)は、ls.onを介して登録されたリスナーを削除します
local-storageは、多くのイベントを登録するのではなく、1つのイベントハンドラーを登録し、監視しているすべてのキーを追跡することに注意してください。
おそらく、タブ間の通信を使用できる他のケースを考え出すことができます。 これまで、SharedWorkerは適切な配布を受けていません。アプリケーションが主にオフラインでの作業に焦点を合わせている場合、WebSocketsアプローチは信頼できません。