javascript 有没有一种可靠的方法可以在浏览器关闭时将用户注销?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5292506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a reliable way to log a user out when the browser is closed?
提问by Mike
I am looking for a reliable way to log out a user or abandon their session when the browser is closed. Is there a way to do this with tabbed browsers?? Any suggestions are appreciated. Thanks!
我正在寻找一种可靠的方法来在浏览器关闭时注销用户或放弃他们的会话。有没有办法用标签浏览器做到这一点?任何建议表示赞赏。谢谢!
回答by BalusC
There is no reliable way to do this immediatelywhen the client closes the browser. There's the beforeunloadevent, but even then, when you fire an ajax request during this event, it's not guaranteed to ever reach the server. Still then, you've a problem with multiple browser tabs.
当客户端关闭浏览器时,没有可靠的方法可以立即执行此操作。有这个beforeunload事件,但即便如此,当您在此事件期间触发 ajax 请求时,也不能保证一定会到达服务器。尽管如此,您还是遇到了多个浏览器选项卡的问题。
Most reliable way is to have a relatively short session timeout in the server side (e.g. 1 minute) and introduce an ajaxbased heartbeat on the client side (e.g. every 30 seconds) to keep the session alive.
最可靠的方法是在服务器端设置一个相对较短的会话超时时间(例如 1 分钟)并在客户端引入一个基于 ajax 的心跳(例如每 30 秒)以保持会话活动。
There may be better ways depending on the sole functional requirement for which you thought that this is the solution. For example, if your actualintent is to restrict all logins to 1 per registered user, then you'd better collect all logins and the associated sessions and then compare this on each login and invalidate the earlier session if any present. This way it'll work as well on clients with JS disabled.
根据您认为这是解决方案的唯一功能需求,可能有更好的方法。例如,如果您的实际意图是将所有登录限制为每个注册用户 1 次,那么您最好收集所有登录和关联的会话,然后在每次登录时进行比较,并使之前的会话无效(如果存在)。这样它也可以在禁用 JS 的客户端上运行。
回答by Karl Nicoll
If you aren't using cookies to preserve your users' login information, it shouldlog them out when they close the browser, because any session cookies should be killed when the browser closes.
如果您不使用 cookie 来保存用户的登录信息,则应在用户关闭浏览器时将其注销,因为在浏览器关闭时应终止任何会话 cookie。
Obviously this isn't always the case (see here for an exampleof Firefox preserving login information after logging out) because "session restore" features we now blur the line between what is considered a "single browser session". (Personally, I think this should be classified as a bug, but that is only my opinion).
显然,情况并非总是如此(有关 Firefox 在注销后保留登录信息的示例,请参见此处),因为“会话恢复”功能现在模糊了“单一浏览器会话”之间的界限。(就我个人而言,我认为这应该归类为错误,但这只是我的意见)。
There are two possible techniques. The first would be (as yojimbo87 mentions before me) to use web sockets to keep a connection between client and server, and when the socket closes, kill the session. The issue here is that web sockets support is limited, and certainly not possible on anything other than bleeding edge browsers (FF4, Chrome, IE9, etc).
有两种可能的技术。第一个是(正如 yojimbo87 在我之前提到的)使用网络套接字来保持客户端和服务器之间的连接,当套接字关闭时,终止会话。这里的问题是 web sockets 支持是有限的,除了最前沿的浏览器(FF4、Chrome、IE9 等)之外,当然不可能。
An alternative could be to use AJAX to constantly poll the server to tell it that the page is still being viewed, so if, for example, you send a keep-alive request via AJAX every 30 seconds, you'd store the timestamp of the request in the session. If the user then comes back to the page and the time difference between the current request and the last request is more than say... 45 seconds (accounting for latency), you'd know that the user closed their browser and need to log in again.
另一种方法是使用 AJAX 不断轮询服务器以告诉它该页面仍在查看中,因此,例如,如果您每 30 秒通过 AJAX 发送一个保持活动的请求,您将存储该页面的时间戳在会话中请求。如果用户随后返回页面并且当前请求和上一个请求之间的时间差超过... 45 秒(考虑到延迟),您就会知道用户关闭了浏览器并需要登录再进去。
In both of these situations, there is however a fatal flaw, and that is that they rely on JavaScript. If the user doesn't have JavaScript enabled, you'd end up ruining the user experience with constant login prompts, which is obviously a bad idea.
然而在这两种情况下,都有一个致命的缺陷,那就是它们依赖于 JavaScript。如果用户没有启用 JavaScript,您最终会因不断出现的登录提示而破坏用户体验,这显然是个坏主意。
In my opinion, I think its reasonable to simply rely on session cookies being deleted by the browser when the user closes the browser window, because that is what they are supposed to do. You as a developer can't be blamed when the client browser performs undesirable behaviour, since its entirely out of your hands, and there's no functional workaround.
在我看来,我认为在用户关闭浏览器窗口时简单地依靠浏览器删除会话 cookie 是合理的,因为这是他们应该做的。当客户端浏览器执行不良行为时,您作为开发人员不能受到责备,因为它完全不受您的控制,并且没有功能性解决方法。
回答by Ondrej Tucny
A feasible technique would be to use AJAX to send keep-alive requests to your servers quite often — e.g. every one minute. Then you could abandon a session as soon as a keep-alive (or a few in sequence) is not received as expected.
一种可行的技术是使用 AJAX 经常向您的服务器发送保持活动的请求——例如每隔一分钟。然后,一旦未按预期接收到保持活动(或顺序中的几个),您就可以放弃会话。
Otherwise, there's no reliable way to achieve that. Since there's not a persistent connection between the browser and the server you can't detect situations that are out-of-control of any JavaScript code you might have running in the browser. For example, when there's a network failure you might want to close the session as well even though the browser's window is still opened. Hence, to make the system robust enough, you should detect network outages as a “side-effect” of the keep-alive mechanism from the browser (e.g. like Gmail does it).
否则,没有可靠的方法来实现这一目标。由于浏览器和服务器之间没有持久连接,因此您无法检测到您可能在浏览器中运行的任何 JavaScript 代码失控的情况。例如,当出现网络故障时,即使浏览器的窗口仍处于打开状态,您也可能希望关闭会话。因此,为了使系统足够健壮,您应该将网络中断检测为浏览器保持活动机制的“副作用”(例如 Gmail 就是这样做的)。
回答by yojimbo87
Unless you are using WebSockets or some kind of long polling for each tab which tracks the connection with client in "real time", you will probably have to wait until the session is timed out on the server side.
除非您使用 WebSockets 或对“实时”跟踪与客户端的连接的每个选项卡使用某种长轮询,否则您可能必须等到会话在服务器端超时。
回答by mrstanfan
You can do this via a combination of Jquery,Ajax and PHP The Jquery
你可以通过 Jquery、Ajax 和 PHP 的组合来做到这一点
function updatestatusOFF(){
// Assuming we have #shoutbox
$('#connection').load('connection.php?user=<?php echo $_SESSION['username']; ?>&offline=true');
}
The before unload script
卸载前脚本
<script>window.onbeforeunload = function() { return updatestatusOFF(); }</script>
and the php you would have to write yourself which i'm more then certain you can do. it isn't the most reliable but it's the easiest way to implement that. if you want real time reporting .. look into comet
和 php 你必须自己写,我更确定你可以做到。它不是最可靠的,但它是实现它的最简单方法。如果你想实时报告......看看彗星

