SessionStorage 浏览器范围(范围)或 LocalStorage 在退出时删除

SessionStorage browser wide (scope) or LocalStorage deleted on exit

是否有任何机制可以让我在浏览器级别处理这些值?我的意思是:

例如,视频在一个选项卡中的播放器中启动。一些标志存储在那种存储中。当用户打开另一个具有相同 URL 的选项卡时,应用程序应读取该标志并禁止播放视频。当然它应该在退出时被删除,否则标志将拒绝该浏览器中所有未来的请求。有什么建议吗?

每个选项卡或 window 数据都可以 save/read 到 local/session 存储,但仅限于该域。

你问的关于两个标签的视频处理的问题,可以解决,但是处理起来非常棘手,我不建议走那条路!您可以定期将视频的时间戳保存到浏览器存储中,但这也取决于将视频发送到浏览器的服务器,您最终可能根本不向用户提供视频!

为了在浏览器 window 关闭时清除数据,我认为没有针对该事件的事件,但是有针对 window 失去焦点的事件,所以我猜您可以使用它。

次,

如果要求是最后一个“只要浏览器 window 打开”,您将遇到重复的问题,因为浏览器不再在该级别上工作 - 有选项卡级别和域级别(像 cookie 一样持久存在)。 “浏览器 Window”只是选项卡的集合,除非您以某种方式专门设置浏览器(在关闭时删除 cookie 和会话数据,并且不在 window 实例之间共享数据)。然而,这是浏览器设置(并且甚至不是跨不同浏览器的标准),而不是您可以在客户端控制的东西。

如果您愿意考虑一些能够提供您似乎需要的最终结果的替代方案(如果不是以您指定的特定方式),请继续阅读:

要扩展 AkshayJ 的原始评论,请使用 localStorage,因为 sessionStorage 仅是特定于选项卡的(无法共享)。

为了清除标志,作为设置标志的相同功能的一部分,向播放视频的选项卡添加一个 onunload 事件,该事件将在选项卡关闭或 window 位置时清除它离开视频。这将允许比您最初请求的功能更多的功能,因为在您原来的情况下,用户必须完全关闭浏览器才能再次播放视频,即使播放视频的选项卡早已消失或已移至另一页。

更新:

如果围绕此的 security/authorization 至关重要(而不是只是想“意外地”阻止它发生),那么使用 localStorage 是完全错误的方法 - 这些数据及其存在最终是受控的由用户。他们可以删除它,或设置他们的浏览器以使 window 个实例不共享数据,因此他们需要做的就是打开一个新的 window 以同时两次观看您的视频。坚定的用户会在几分钟内找到解决方法。

如果你想绝对控制它,你必须在这个域端而不是依赖浏览器存储,并使用一些其他标签,如当前访问的 IP 列表,或其他识别唯一用户的方法, 判断视频是否可以播放。请记住,无论是浏览器端还是域端,您都会遇到与以前相同的问题,即何时清除标志。

更新:

回复:使用什么事件,onunloadonbeforeunload 似乎在所有常见浏览器中都得到完全支持(参考:Here and Here). This Answer 为了安全起见,建议同时使用。

更新:

OP 表示担心卸载事件不可靠,如果出现问题,用户可能会永远被锁定。就我个人而言,我在这里没有遇到任何不可靠性,但如果您担心,请引入超时方面。让播放视频的选项卡每 30 seconds/1 minute/whatever 使用时间戳更新标志(无论存储在何处)。然后当页面的新实例加载时,让它检查时间戳。如果现有页面发生某些事情,导致它冻结和卸载事件没有 运行,时间戳将过时,因为它也将停止更新,因此您只需要检查时间戳是否已过期日期以及检查是否存在。

$(window).on('beforeunload', function DecideAction() {
   if (('localStorage' in window) && window['localStorage'] !== null) {
      //get value from localstorage using getItem and allow/deny the further access
   }
});

最后我放弃了服务器端会话,因为它引发了其他问题,并用这个工作流程解决了它:

  • 页面加载后,localStorage 值被设置(如果之前没有),并标记播放器已在此选项卡中打开。如果已设置 localStorage,则标志设置为 false。

  • 如果设置flag,则播放视频,否则禁止。

  • 在页面卸载时,只有设置了标志(即,如果用户在此选项卡中打开了视频),删除 localStorage 值。

$(function () {
    if (localStorage.playerTabOpened) {
        var dateNow = Date.now();
        var diffSinceLastTabOpened = (dateNow - localStorage.playerTabOpened) / 1000;
        // if playerTabOpened value was stored more than 1 day ago, delete it anyway because it could be left by chance
        if (diffSinceLastTabOpened > 86400) {
            localStorage.removeItem("playerTabOpened");
        };
    }
    if (!localStorage.playerTabOpened) {
        shared.playerTabOpenedHere = true;
        localStorage.setItem("playerTabOpened", Date.now());
    } else {
        shared.playerTabOpenedHere = false;
    }
});

$(window).on("beforeunload", function () {
    if (shared.playerTabOpenedHere) {
        localStorage.removeItem("playerTabOpened");
    }
});

if (shared.playerTabOpenedHere) {
    // play
} else {
    // throw error
}