sessionStorage browser. bagikan antar tab?

151

Saya memiliki beberapa nilai di situs saya yang ingin saya hapus ketika browser ditutup. Saya memilih sessionStorageuntuk menyimpan nilai-nilai itu. Ketika tab ditutup mereka memang dihapus, dan disimpan jika pengguna menekan f5; Tetapi jika pengguna membuka beberapa tautan di tab berbeda nilai-nilai ini tidak tersedia.

Bagaimana saya bisa berbagi sessionStoragenilai antara semua tab browser dengan aplikasi saya?

Kasing penggunaan: masukkan nilai di beberapa penyimpanan, pertahankan nilai itu dapat diakses di semua tab peramban dan hapus jika semua tab ditutup.

if (!sessionStorage.getItem(key)) {
    sessionStorage.setItem(key, defaultValue)
}
Vladimir Gordienko
sumber
9
Aneh bagi saya bahwa ini ditutup sebagai duplikat. Nominasi untuk dibuka kembali. Topik lainnya adalah tentang "bagaimana berkomunikasi di antara banyak tab", yang terdengar berbeda, dan juga berbeda, ketika saya mulai membaca topik lainnya.
KajMagnus
Apakah mungkin menggunakan cookie? yang berperilaku seperti itu secara default? (tetapi memang - untuk mendapatkan dan menetapkan tindakan mereka akan menuntut implementasi lebih lanjut) developer.mozilla.org/en-US/docs/Web/API/Document/cookie
lingar

Jawaban:

133

Anda dapat menggunakan localStorage dan eventListener "penyimpanan" untuk mentransfer data sessionStorage dari satu tab ke tab lainnya.

Kode ini harus ada di SEMUA tab. Itu harus dijalankan sebelum skrip Anda yang lain.

// 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');
};

Saya menguji ini di chrome, ff, safari, yaitu 11, yaitu 10, ie9

Metode ini "harus bekerja di IE8" tetapi saya tidak dapat mengujinya karena IE saya macet setiap kali saya membuka tab .... sembarang tab ... di situs web mana pun. (IE IE bagus) PS: Anda jelas perlu menyertakan JSON shim jika Anda ingin dukungan IE8 juga. :)

Kredit diberikan untuk artikel lengkap ini: http://blog.guya.net/2015/06/06/sharing-sessionstorage-between-tabs-for-secure-multi-tab-authentication/

nawlbergs
sumber
2
Seberapa andalkah solusi ini? Karena berbasis acara, apakah ada kemungkinan melewatkan acara?
vivek241
2
Berdasarkan jawaban di sini saya membuat perpustakaan di atas Penyimpanan lokal dan sessionStorage untuk menyederhanakan ini. Jadi sekarang Anda tinggal memanggil storageManager.saveSyncedSessionData ('data', 'key'); atau storageManager.savePermanentData ('data', 'key') ;, dll berdasarkan apa yang Anda butuhkan. Kode lengkapnya ada di sini: ebenmonney.com/blog/…
adentum
@ vivek241 Solusinya bekerja sangat baik untuk saya ketika ukuran file JS lebih kecil dan "script solusi" yang diberikan di atas dimuat sebagai skrip pertama di halaman. Ketika file JS saya tumbuh terlalu besar, katakanlah 1000 atau lebih baris, tiba-tiba berhenti bekerja dan menghapus cookie saya dan data penyimpanan lokal tertentu juga. Saya tidak yakin ini adalah solusi yang dapat diandalkan atau lintas-browser yang bisa diandalkan. Jadi, tulis ulang semua logika untuk menyelesaikan masalah dengan cookie saja.
webblover
4
Bukankah acara akan dipicu di semua tab yang sebelumnya terbuka?
Dtipson
3
Sepertinya BroadcastChannelsekarang menjadi alat yang baik untuk melakukan ini. developers.google.com/web/updates/2016/09/broadcastchannel
alexbea
71

Menggunakan sessionStorageuntuk ini tidak mungkin.

Dari Dokumen MDN

Membuka halaman di tab atau jendela baru akan menyebabkan sesi baru dimulai.

Itu berarti Anda tidak dapat berbagi di antara tab, karena ini yang harus Anda gunakan localStorage

Henrik Andersson
sumber
8
Oke, saya mengerti, tapi bagaimana saya bisa menghapus localStorage ketika semua tab browser ditutup?
Vladimir Gordienko
Anda dapat mengubah cookie dokumen path='/'sehingga memaksa untuk menghapus ketika jendela browser ditutup. Tetapi untuk tab, saya tidak tahu sekarang.
Henrik Andersson
ok saya akan menggali lebih dalam dan memberi tahu Anda jika saya menemukan solusi, biarkan berpikir untuk saat ini apa yang tidak mungkin))
Vladimir Gordienko
5
@Anmol ya, tapi saya tidak bisa memberikan kode apa pun, sudah lama sekali. ini adalah solusi jelek tapi itu bekerja untuk saya dengan sempurna. Kuncinya adalah untuk menjaga penghitung tabsOpened di penyimpanan lokal dan meningkatkannya pada halaman memuat tetapi mengurangi pada halaman membongkar. Jadi ketika halaman dibuka dan tabsOpen == 1 tab terakhirnya dan kami dapat menghapus semua hal. Ada beberapa hal kecil yang perlu saya tangani tetapi tidak ingat persis apa. Semoga ini akan membantu Anda!
Vladimir Gordienko
1
@VladimirGordienko bagaimana jika peristiwa bongkar yang menghapus localStoragedata terjadi karena seseorang menavigasi ke domain yang berbeda, di tab yang sama. Menurut saya ini akan menghapus localStoragedata secara tidak benar - tab tidak ditutup, dan jika orang tersebut menavigasi kembali, ia akan menginginkan data itu lagi, benar. Bagaimanapun, ini pendekatan yang menarik, tidak memikirkan itu: -)
KajMagnus
9
  1. Anda bisa menggunakan localStoragedan mengingat tanggal pertama kali dibuat session cookie. Ketika localStorage"sesi" lebih tua dari nilai cookie maka Anda dapat menghapuslocalStorage

    Kontra dari hal ini adalah seseorang masih dapat membaca data setelah browser ditutup sehingga ini bukan solusi yang baik jika data Anda bersifat pribadi dan rahasia.

  2. Anda dapat menyimpan data Anda localStorageselama beberapa detik dan menambahkan pendengar acara untuk suatu storageacara. Dengan cara ini Anda akan tahu kapan salah satu tab menulis sesuatu ke localStoragedan Anda dapat menyalin kontennya ke sessionStorage, lalu hapus sajalocalStorage

Adassko
sumber
0

Solusi saya untuk tidak memiliki sessionStorage yang dapat dipindahtangankan melalui tab adalah membuat Profil lokal dan menghapus variabel ini. Jika variabel ini disetel tetapi variabel sessionStorage saya tidak berjalan dan menginisialisasi ulang mereka. Ketika pengguna keluar dari jendela, hancurkan variabel localStorage ini

yardpenalty.com
sumber
-14

Berikut adalah solusi untuk mencegah sesi geser antara tab browser untuk aplikasi java. Ini akan berfungsi untuk IE (JSP / Servlet)

  1. Di halaman JSP pertama Anda, onload acara panggil servlet (ajex call) untuk mengatur "window.title" dan pelacak peristiwa dalam sesi (hanya variabel integer yang akan ditetapkan sebagai 0 untuk pertama kali)
  2. Pastikan tidak ada halaman lain yang mengatur window.title
  3. Semua halaman (termasuk halaman pertama) menambahkan skrip java untuk memeriksa judul jendela setelah memuat halaman selesai. jika judul tidak ditemukan maka tutup halaman / tab saat ini (pastikan untuk membatalkan fungsi "window.unload" ketika ini terjadi)
  4. Setel window.onunload event skrip java (untuk semua halaman) untuk menangkap event refresh halaman, jika sebuah halaman telah di-refresh, panggil servlet untuk mereset pelacak event.

1) JS halaman pertama

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 umum untuk semua halaman

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 - pemetaan servlet

<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) kode servlet

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");
} 
  }
DTB
sumber
3
Pertanyaan ini tentang javascript, tidak ada hubungannya dengan javascript.
victorpacheco3107
Ini adalah pertanyaan lebih lanjut tentang sessionStorage dan localStorage
RR1112