我知道這個職位是很老,但在情況下,它可以幫助任何人,我最近看着基本上是做使用的localStorage和sessionStorage的同樣的事情。
類似Anthony's answer,它設置一個時間間隔以確保始發選項卡保持條目新鮮,以便在瀏覽器崩潰或以某種方式關閉時不調用卸載事件(包含在註釋中但不包含在用於測試目的的代碼的一部分中),那麼在應用程序在新的瀏覽器窗口中正常運行之前就會有一段短暫的延遲。
很明顯,你會改變「選項卡是好的」,「選項卡是壞」的條件來做任何你想要的邏輯。
哦,而且,createGUID方法只是一個實用工具,使會話標識符具有唯一性...它從this answer到上一個問題(希望確保我沒有爲此付出代價)。
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';
}
那麼你可以有一點點的JavaScript後心跳請求飄飛與當前用戶的會話ID,你檢查這AJAX心跳在未來的頁面加載前對於本次會話,如果是,則終止它。 – gideon
您可能可以爲有限的一組案件做到這一點,但總的來說這是不可能的。用戶可以禁用部分或全部腳本,拒絕訪問cookie和歷史記錄,並且某些瀏覽器允許在選項卡中啓動全新的會話,因此除了IP嗅探(服務器可以輕鬆完成)之外,您運氣不佳。 – RobG