我现在使用的是 window.sessionStorage 来存储一个唯一生成的会话ID。这个ID会被传递给所有对服务器的ajax调用,并在页面导航和重新加载时持续存在。
这似乎在我的目标浏览器中工作得很完美,但有一点需要注意:Chrome中的复制标签功能。
复制标签页会将会话存储复制到新的标签页中。当新标签页加载并与服务器通信时,它现在拥有与复制的目标标签页相同的 "唯一 "标识符。
有什么方法可以区分这两个重复的标签页吗? 或者它们真的是重复的,而且这两个标签页之间没有任何信息是不同的?
在tabwindow关闭后,没有任何东西会持久存在,所以即使是一个简单的数字标签ID或任何东西也可以工作,只要它对当前实例是唯一的。
会话存储是在浏览器级别,而不是在标签级别。请看 https:/developer.mozilla.orgen-USdocsWebAPIWindows会话存储。 .
我所知道的唯一识别标签的方法是在每个URL的末尾传递一个paramater(即使如此,你也需要使用JavaScript来防止在新Tab中打开)。
其他方法会让人无法忍受,比如在应用中嵌入一个iframe(并将标识符存储在父体中),但有可能。
简而言之,你应该把你的问题重新表述为简单地识别一个Tab,你将永远找不到答案。
我最终的解决方案是在服务器端生成一个唯一的ID,这个ID会被存储在服务器会话中,并传回存储在sessionStorage中。我还有另一个值(我们称它为FOO),在客户端设置并存储.假装它在地图中是这样的。
{
"unique_id" : "ABC123",
"FOO" : "some value"
}
我在每次ajax请求时,都会把这些值发送到服务器上。
在页面加载时,我检查是否在sessionStorage中已经有了unique_id,FOO对,并加载它们。任何时候FOO的值发生变化时,它都会与服务器对进行比较。如果它有一个不同的值,那么我将FOO的新值存储在一个 新的 独一无二的ID,并把它交还给客户端。
这并不能100%解决这个问题,但它可以确保代表某种持久化状态的FOO在标签复制后永远不会被错误地使用.原来拥有unique_id、FOO对的标签页将继续拥有这对标签,而被复制的标签页将拥有新的对。
从技术上讲,在FOO的值改变之前,两个tab共享相同的unique_id,但只要在FOO改变时unique_id被重新分配,它们就不会在服务器会话中覆盖对方的状态。
一个变种的方法对我来说是可行的。
https: /stackoverflow.coma6016411113375384
诀窍是在刷新标签页的短暂时间内,只把ID放在会话存储中
在我的TypeScript项目中,解决方案看起来像这样。
const tabIdKey = "tabIdStorageKey"
const initTabId = (): string => {
const id = sessionStorage.getItem(tabIdKey)
if (id) {
sessionStorage.removeItem(tabIdKey)
return id
}
return uuid()
}
const tabId = initTabId()
window.addEventListener("beforeunload", () => {
sessionStorage.setItem(tabIdKey, tabId)
})