Javascript 不允许同时在多个浏览器/选项卡中登录网站
我有一个重ajax的网站,当用户同时在多个浏览器窗口中打开它时,它会中断(或显示不正确的数据)。因此,我想强制执行一次只允许用户在一个选项卡中登录网站,无论它是在同一台计算机上还是在多台计算机上 我正在寻找如何做到这一点的想法 是否有JavaScript方法来判断某个页面是否已在另一个选项卡中打开 可能还有另一种解决方案涉及服务器端 例如,客户端可以每隔1分钟向服务器发送一条消息。如果服务器以高于每分钟一条消息的频率从特定用户处获取消息,则它知道它在多个窗口或选项卡中打开。然后,它可以让其中一个客户端知道它需要向用户喊出一个错误 不过,每一分钟向服务器发送一次消息的想法并不适合我 还有其他想法吗 编辑:有些人想知道我为什么会有这个问题。下面是:Javascript 不允许同时在多个浏览器/选项卡中登录网站,javascript,client-server,Javascript,Client Server,我有一个重ajax的网站,当用户同时在多个浏览器窗口中打开它时,它会中断(或显示不正确的数据)。因此,我想强制执行一次只允许用户在一个选项卡中登录网站,无论它是在同一台计算机上还是在多台计算机上 我正在寻找如何做到这一点的想法 是否有JavaScript方法来判断某个页面是否已在另一个选项卡中打开 可能还有另一种解决方案涉及服务器端 例如,客户端可以每隔1分钟向服务器发送一条消息。如果服务器以高于每分钟一条消息的频率从特定用户处获取消息,则它知道它在多个窗口或选项卡中打开。然后,它可以让其中一个
这是一个完全支持ajax的时间跟踪应用程序。您可以使用ajax浏览/创建/删除/修改计时器、项目和客户端,而无需离开页面。如果网站在多个标签页中打开,事情很快就会变得不一致。错误通常甚至会发生。例如,用户创建一个项目,然后在tab1中启动一个计时器,tab2不会显示这些更改。由于它都是ajax,所以当用户单击第二个选项卡中的某个按钮时,它不会简单地同步。在javascript中无法获取有关其他选项卡/窗口的信息(这是有充分理由的) 我认为最好的方法是在每个页面的javascript代码中打印一个唯一标识符(时间戳应该可以很好地工作),然后定期使用该唯一ID ping服务器,并在服务器上将其与用户关联。这样,如果在给定的时间间隔内ping了一个用户的多个ID,则可以向页面发回响应,警告用户打开多个选项卡将导致意外行为
(就像Caspar在上面所说的,你应该真正弄清楚为什么会发生意外行为,并加以纠正,而不是强迫用户以某种方式行事)这是相当低的保真度,但我认为简单性可能会让它起作用:你可以尝试让登录名在命名窗口中打开会话(或更改当前窗口的名称). 然后,在应用程序内部加载时,检查浏览器窗口名称是否是您允许他们使用的名称;如果没有,弹出警报,关闭窗口,关注指定的窗口(如果仍然存在)。(如果没有,也就是说,他们已经关闭了另一个窗口,您可以让这个窗口保持打开状态,并将名称更改为正确的名称。)
因此,实际上您使用的是
window.name
和window.opener
。大致的想法,但是一个想法。阅读了您问题中的更新之后,我真正建议的是在可用的情况下使用WebSocket,回到Flash socket,长时间轮询,以及针对较旧浏览器的永久iframe(实际上,我会使这一切变得简单-无论您使用什么环境,都可以使用类似的抽象)。这样,您可以使您的所有窗口和选项卡实时一致-问题得到解决
已经说过,如果你出于某种原因不想这样做(尽管你正在尝试的是一个完美的WebSocket应用程序,请仔细想想),你可以使用sessionStorage和localStorage来区分同一登录用户的选项卡或窗口之间的会话,但是它还没有被广泛使用-请参阅,因此,在有很多可用的回退的情况下,实时使用类似socket.io的解决方案可能比将访问者限制在一个选项卡上更容易,更不用说用户体验了。我也有类似的情况,我使用的解决方案是:
$(window).on('beforeunload onbeforeunload', function(){
document.cookie = 'ic_window_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
});
function validateCallCenterTab() {
var win_id_cookie_duration = 10; // in seconds
if (!window.name) {
window.name = Math.random().toString();
}
if (!getCookie('ic_window_id') || window.name === getCookie('ic_window_id')) {
// This means they are using just one tab. Set/clobber the cookie to prolong the tab's validity.
setCookie('ic_window_id', window.name, win_id_cookie_duration);
} else if (getCookie('ic_window_id') !== window.name) {
// this means another browser tab is open, alert them to close the tabs until there is only one remaining
var message = 'You cannot have this website open in multiple tabs. ' +
'Please close them until there is only one remaining. Thanks!';
$('html').html(message);
clearInterval(callCenterInterval);
throw 'Multiple call center tabs error. Program terminating.';
}
}
callCenterInterval = setInterval(validateCallCenterTab, 3000);
}这闻起来像是你试图在一个不应该解决的端点解决一个设计问题。它正在造成赛车状况。但是,为什么您不能修复(或询问)服务器上出现的问题?您的编辑证实了我的怀疑;)。您确实需要在服务器上修复此问题。在输出gui的应用程序中有很多业务逻辑吗?是的,有很多业务逻辑。我想我需要在浏览器上打开一个端口,这样当另一个浏览器选项卡更改某些内容时,服务器可以向浏览器发送消息。我想这很难实现。你可以自己去看看这个网站。。但我不想从这里链接到它。但你可以在这里找到:我刚刚研究了服务器推送,它看起来很复杂。也许服务器轮询是可以的,但有时用户会直接访问wor