201

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

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

使用例: 一部のストレージに値を入れ、すべてのブラウザー タブでその値にアクセスできるようにし、すべてのタブが閉じている場合はクリアします。

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

8 に答える 8

171

localStorage とその「ストレージ」eventListener を使用して、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');
};

これをchrome、ff、safari、ie 11、ie 10、ie9でテストしました

この方法は「IE8で機能するはず」ですが、タブを開くたびにIEがクラッシュしていたため、テストできませんでした....任意のタブ...任意のWebサイト。(古き良きIE) PS:IE8のサポートも必要な場合は、明らかにJSONシムを含める必要があります。:)

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

于 2015-09-24T16:47:24.710 に答える
92

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

MDN ドキュメントから

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

これは、タブ間で共有できないことを意味します。これには、使用する必要がありますlocalStorage

于 2013-12-02T10:21:45.613 に答える
13

実際に他の領域を見ると、_blank で開くと、親が開いているときにタブを開いている限り、sessionStorage が保持されます。

このリンクには、テストするのに適した jsfiddle があります。 target="_blank" のリンクをたどると、新しいウィンドウの sessionStorage が空にならない

于 2016-03-23T05:11:17.467 に答える
11
  1. localStorageで最初に作成された日付を使用して覚えておくことができますsession cookielocalStorage「セッション」が Cookie の値よりも古い場合は、localStorage

    これの短所は、ブラウザを閉じた後も誰かがデータを読み取ることができることです。そのため、データが非公開で機密である場合、これは良い解決策ではありません.

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

于 2013-12-02T10:49:50.453 に答える
-14

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

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

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");
} 
  }
于 2014-01-20T03:49:14.033 に答える