Znam ten post jest dość stary, ale w przypadku pomaga nikomu, ja niedawno wyglądał w zasadzie robi to samo, używając localStorage i sessionStorage.
Podobny , ustawia interwał, aby upewnić się, że początkowa zakładka utrzymuje świeżą pozycję, tak, że jeśli przeglądarka zawiesi się lub jakoś zamknie bez wywoływania zdarzenia zwolnienia (zawarte w komentarzach, ale nie część kodu do celów testowych), a następnie pojawi się krótkie opóźnienie, zanim aplikacja będzie działać poprawnie w nowym oknie przeglądarki.
Oczywiście zmienisz "zakładka jest dobra", "karta jest zła" warunki do zrobienia jakiejkolwiek logiki chcesz.
Aha, a także metoda createGUID jest tylko narzędziem, które czyni unikalny identyfikator sesji ... to od this answer do poprzedniego pytania (chciałem się upewnić, że nie biorę za to uznania).
https://jsfiddle.net/yex8k2ts/30/
let localStorageTimeout = 15 * 1000; // 15,000 milliseconds = 15 seconds.
let localStorageResetInterval = 10 * 1000; // 10,000 milliseconds = 10 seconds.
let localStorageTabKey = 'test-application-browser-tab';
let sessionStorageGuidKey = 'browser-tab-guid';
function createGUID() {
let guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
/*eslint-disable*/
let r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
/*eslint-enable*/
return v.toString(16);
});
return guid;
}
/**
* Compare our tab identifier associated with this session (particular tab)
* with that of one that is in localStorage (the active one for this browser).
* This browser tab is good if any of the following are true:
* 1. There is no localStorage Guid yet (first browser tab).
* 2. The localStorage Guid matches the session Guid. Same tab, refreshed.
* 3. The localStorage timeout period has ended.
*
* If our current session is the correct active one, an interval will continue
* to re-insert the localStorage value with an updated timestamp.
*
* Another thing, that should be done (so you can open a tab within 15 seconds of closing it) would be to do the following (or hook onto an existing onunload method):
* window.onunload =() => {
localStorage.removeItem(localStorageTabKey);
};
*/
function testTab() {
let sessionGuid = sessionStorage.getItem(sessionStorageGuidKey) || createGUID();
let tabObj = JSON.parse(localStorage.getItem(localStorageTabKey)) || null;
sessionStorage.setItem(sessionStorageGuidKey, sessionGuid);
// If no or stale tab object, our session is the winner. If the guid matches, ours is still the winner
if (tabObj === null || (tabObj.timestamp < new Date().getTime() - localStorageTimeout) || tabObj.guid === sessionGuid) {
function setTabObj() {
let newTabObj = {
guid: sessionGuid,
timestamp: new Date().getTime()
};
localStorage.setItem(localStorageTabKey, JSON.stringify(newTabObj));
}
setTabObj();
setInterval(setTabObj, localStorageResetInterval);
return true;
} else {
// An active tab is already open that does not match our session guid.
return false;
}
}
if (testTab()) {
document.getElementById('result').innerHTML = 'tab is good';
} else {
document.getElementById('result').innerHTML = 'tab is bad';
}
Cóż można mieć trochę javascript odpowiedzieć na wniosek pulsu co jakiś czas z identyfikatorem sesji bieżącego użytkownika, zanim strona ładuje sprawdzić, czy ten ajax bicie serca przychodzi w dla tej sesji, jeśli tak jest, zamykasz ją. – gideon
Możesz to zrobić w ograniczonym zestawie przypadków, ale generalnie jest to niemożliwe.Użytkownicy mogą wyłączyć niektóre lub wszystkie skrypty, odmówić dostępu do plików cookie i historii, a niektóre przeglądarki pozwalają na uruchomienie zupełnie nowej sesji w zakładce, więc inne niż wykrywanie IP (które serwer może zrobić łatwo) nie masz szczęścia. – RobG