ブラウザsessionStorage。タブ間で共有しますか?


151

私のサイトには、ブラウザを閉じたときにクリアしたい値がいくつかあります。私が選んだsessionStorageそれらの値を格納します。タブが閉じられると、それらは実際にクリアされ、ユーザーがf5を押しても保持されます。ただし、ユーザーが別のタブでリンクを開いた場合、これらの値は使用できません。

sessionStorageアプリケーションですべてのブラウザタブ間で値を共有するにはどうすればよいですか?

使用例:値を何らかのストレージに配置し、その値をすべてのブラウザータブでアクセスできる状態に保ち、すべてのタブが閉じている場合は値をクリアします。

if (!sessionStorage.getItem(key)) {
    sessionStorage.setItem(key, defaultValue)
}

9
これが複製として閉じられたのは奇妙です。再開のために指名。もう1つのトピックは、「複数のタブ間で通信する方法」に関するものです。これは、他のトピックを読み始めると、音が異なり、また異なります。
KajMagnus

クッキーを使用することは可能ですか?デフォルトではそのように動作しますか?(しかし、確かに
-get

回答:


133

localStorageとその「ストレージ」eventListenerを使用して、1つのタブから別のタブにsessionStorageデータを転送できます。

このコードは、すべてのタブに存在する必要があります。他のスクリプトの前に実行する必要があります。

// transfers sessionStorage from one tab to another
var sessionStorage_transfer = function(event) {
  if(!event) { event = window.event; } // ie suq
  if(!event.newValue) return;          // do nothing if no value to work with
  if (event.key == 'getSessionStorage') {
    // another tab asked for the sessionStorage -> send it
    localStorage.setItem('sessionStorage', JSON.stringify(sessionStorage));
    // the other tab should now have it, so we're done with it.
    localStorage.removeItem('sessionStorage'); // <- could do short timeout as well.
  } else if (event.key == 'sessionStorage' && !sessionStorage.length) {
    // another tab sent data <- get it
    var data = JSON.parse(event.newValue);
    for (var key in data) {
      sessionStorage.setItem(key, data[key]);
    }
  }
};

// listen for changes to localStorage
if(window.addEventListener) {
  window.addEventListener("storage", sessionStorage_transfer, false);
} else {
  window.attachEvent("onstorage", sessionStorage_transfer);
};


// Ask other tabs for session storage (this is ONLY to trigger event)
if (!sessionStorage.length) {
  localStorage.setItem('getSessionStorage', 'foobar');
  localStorage.removeItem('getSessionStorage', 'foobar');
};

私はこれをクロム、ff、サファリ、つまり11、すなわち10、ie9でテストしました

この方法は「IE8で動作するはずです」が、タブを開くたびにIEがクラッシュしたため、テストできませんでした。(good ol IE)PS:IE8のサポートも必要な場合は、JSONシムを含める必要があることは明らかです。:)

クレジットはこの完全な記事に行きます:http : //blog.guya.net/2015/06/12/sharing-sessionstorage-between-tabs-for-secure-multi-tab-authentication/


2
このソリューションはどの程度信頼できますか?イベントベースなので、イベントを見逃す可能性はありますか?
vivek241 2015年

2
ここでの回答に基づいて、localStorageとsessionStorageを介してライブラリを作成し、これを簡素化しました。そのため、今ではstorageManager.saveSyncedSessionData( 'data'、 'key');を呼び出すだけです。またはstorageManager.savePermanentData( 'data'、 'key');など、必要に応じて。完全なコードはここにある:ebenmonney.com/blog/...
adentum

@ vivek241 JSファイルのサイズが小さく、上記の「ソリューションスクリプト」がページの最初のスクリプトとしてロードされている場合、ソリューションはうまく機能しました。JSファイルが大きくなりすぎて、たとえば1000行以上になると、突然動作を停止し、Cookieと特定のlocalStorageデータも削除されました。これが信頼できるブラウザ間ソリューションであるかどうかはわかりません。したがって、Cookieのみで問題を解決するためにすべてのロジックを書き直しました。
webblover 2017年

4
以前に開いていたすべてのタブでイベントがトリガーされませんか?
Dtipson 2017年

3
これBroadcastChannelは、これを行うための優れたツールになりました。developers.google.com/web/updates/2016/09/broadcastchannel
alexbea

71

これに使用sessionStorageすることはできません。

MDNドキュメントから

新しいタブまたはウィンドウでページを開くと、新しいセッションが開始されます。

つまり、タブ間で共有することはできません。これを使用するには、 localStorage


8
わかりましたが、すべてのブラウザタブが閉じているときにlocalStorageをクリアするにはどうすればよいですか?
Vladimir Gordienko、

ドキュメントのCookieを変更してpath='/'、ブラウザウィンドウを閉じたときに強制的にクリアするようにできます。しかし、タブについては、現時点ではわかりません。
Henrik Andersson、

わかりました、私はより深く掘り下げて、私が解決策を見つけた場合はあなたに知らせます、今のところそれが不可能なことを考えましょう))
Vladimir Gordienko

5
@Anmolはい、でもコードを提供することはできません。これは醜い解決策ですが、私にとっては完璧に機能します。そこで重要なのは、tabsOpenedカウンターをローカルストレージに保持し、ページの読み込み時にそれを増やし、ページのアンロード時に減らすことです。したがって、ページがアンロードされ、tabsOpen == 1になると、最後のタブが表示され、すべてをクリアできます。私が処理する必要があるいくつかのマイナーなことがありましたが、正確に何を思い出すことができません。それがあなたを助けることを願っています!
Vladimir Gordienko 2016年

1
@VladimirGordienko localStorage誰かが同じタブで別のドメインに移動したためにデータを削除するアンロードイベントが発生した場合 これはlocalStorageデータを誤って削除するように思えます—タブが閉じられなかったため、ユーザーが戻ってナビゲートした場合、データが再び必要になります。とにかく、それは興味深いアプローチで、それについては考えていませんでした:-)
KajMagnus

9
  1. localStorageで最初に作成された日付を使用して覚えることができsession cookieます。ときにlocalStorage「セッション」は、Cookieの値よりも古いですあなたはクリアすることがありlocalStorage

    これの短所は、ブラウザが閉じられた後でも誰かがデータを読み取ることができることです。そのため、データがプライベートで自信がある場合は、良い解決策ではありません。

  2. データをlocalStorage数秒間保存し、イベントのイベントリスナーを追加できstorageます。これにより、いずれかのタブがに何かを書き込んだことがわかり、localStorageそのコンテンツをにコピーしてsessionStoragelocalStorage



0

タブを介してセッションストレージを転送できないようにする私の解決策は、localProfileを作成し、この変数をオフにすることでした。この変数が設定されているが、私のsessionStorage変数が先に進んでいない場合は、それらを再初期化してください。ユーザーがログアウトウィンドウを閉じると、このlocalStorage変数が破棄されます


-14

これは、Javaアプリケーションのブラウザタブ間のセッションシェアリングを防ぐためのソリューションです。これはIE(JSP /サーブレット)で動作します

  1. 最初のJSPページで、onloadイベントがサーブレット(ajex呼び出し)を呼び出して、セッションに「window.title」とイベントトラッカーを設定します(最初は整数変数を0に設定するだけです)。
  2. 他のページでwindow.titleが設定されていないことを確認してください
  3. すべてのページ(最初のページを含む)は、ページのロードが完了すると、ウィンドウのタイトルをチェックするJavaスクリプトを追加します。タイトルが見つからない場合は、現在のページ/タブを閉じます(これが発生した場合は、「window.unload」関数を元に戻してください)。
  4. ページが更新されている場合は、ページwindow.onunload JavaScriptスクリプトイベント(すべてのページ)を設定してページ更新イベントをキャプチャし、サーブレットを呼び出してイベントトラッカーをリセットします。

1)最初のページのJS

BODY onload="javascript:initPageLoad()"

function initPageLoad() {
    var xmlhttp;

    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else {
        // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {                           var serverResponse = xmlhttp.responseText;
            top.document.title=serverResponse;
        }
    };
                xmlhttp.open("GET", 'data.do', true);
    xmlhttp.send();

}

2)すべてのページに共通のJS

window.onunload = function() {
    var xmlhttp;
    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else {
        // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {             
            var serverResponse = xmlhttp.responseText;              
        }
    };

    xmlhttp.open("GET", 'data.do?reset=true', true);
    xmlhttp.send();
}

var readyStateCheckInterval = setInterval(function() {
if (document.readyState === "complete") {
    init();
    clearInterval(readyStateCheckInterval);
}}, 10);
function init(){ 
  if(document.title==""){   
  window.onunload=function() {};
  window.open('', '_self', ''); window.close();
  }
 }

3)web.xml-サーブレットマッピング

<servlet-mapping>
<servlet-name>myAction</servlet-name>
<url-pattern>/data.do</url-pattern>     
</servlet-mapping>  
<servlet>
<servlet-name>myAction</servlet-name>
<servlet-class>xx.xxx.MyAction</servlet-class>
</servlet>

4)サーブレットコード

public class MyAction extends HttpServlet {
 public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException {
    Integer sessionCount = (Integer) request.getSession().getAttribute(
            "sessionCount");
    PrintWriter out = response.getWriter();
    Boolean reset = Boolean.valueOf(request.getParameter("reset"));
    if (reset)
        sessionCount = new Integer(0);
    else {
        if (sessionCount == null || sessionCount == 0) {
            out.println("hello Title");
            sessionCount = new Integer(0);
        }
                          sessionCount++;
    }
    request.getSession().setAttribute("sessionCount", sessionCount);
    // Set standard HTTP/1.1 no-cache headers.
    response.setHeader("Cache-Control", "private, no-store, no-cache, must-                      revalidate");
    // Set standard HTTP/1.0 no-cache header.
    response.setHeader("Pragma", "no-cache");
} 
  }

3
この質問はJavaScriptに関するもので、JavaScriptとは関係ありません。
victorpacheco3107 2016

これは、sessionStorageとlocalStorageについての質問です
RR1112 '11 / 11/19
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.