页面关闭弹出提示并注销登录(兼容主流浏览器)
这是多么普遍而又正常的需求啊,然而在多浏览器时代,这又是多么难做啊~~(我不是FE,我是Java工程师)
目前这个代码能够兼容以下浏览器(我亲测过的):
IE8,Chrome12,Firefox5,Safari4
应该也能支持以下浏览器:
IE7,Chrome8以后的版本,Firefox3.6,4
由于我们的系统不支持IE6,因此就不考虑这个问题了,估计应该没啥问题。
由于Opera不支持beforeunload事件,因此不会弹出提示让用户决定是否退出,同时对于刷新回退等操作也不会调用unlaod,因为它认为那是reload,会直接从cache中获得。我唯一成功响应Opera的unload事件是将Opera关闭了,然后再打开由于它会保留上次的标签,因此会重新加载,就在这个时候它响应了unload。因此放弃对Opera的支持,毕竟我们的服务对象没什么人用。
本来的逻辑是当用户关闭或者刷新或者后退时会弹出一个提示框询问用户是否真的关闭,这里面有以下几个技术陷阱:
1 这个事情只能通过beforeunload完成,但是一旦注册了这个事件,浏览器就会弹出个确认框,不需要你自己写什么confirm,我起初不知道,因为使用了一个开源的产品,找遍了它所有的代码想解除绑定或者屏蔽那个确认框,后来才发现原来是浏览器内置的!
其用法如下:
window.onbeforeunload=function(){
return 'Are you really going to leave?';
}
注意这个地方IE,Firefox,Chrome,各不相同,Safari跟IE相同:
IE和Safari会显示一段内置的话,然后中间显示你这句话;
Firefox只会显示它内置的提示;
Chrome只会显示你写的这段话。
后面让人崩溃的浏览器差异还有很多。
2 当刷新或后退时,执行的流程是beforeunload事件,unload事件和load事件。
但是IE会弹出两次那个提示框。
3 当unload事件触发时,退出登录,有两种方法:
1)发送Ajax请求退出
2)location.href
但是,Chrome和Safari(这俩浏览器是一个内核)在unload方法里执行location.href无效。
按照网上说的各种方法,比如window.location,self.location,navigate.go(0)等等,都无效。
然后使用window.close替代,也无效,后来发现可以这样:
window.open('', '_self', ''); //bug fix
window.close();
这样搞完又会弹两次框。这很正常,因为又打开了一个窗口嘛。
4 Chrome执行完unload事件后,因为没有执行location.href因此继续执行onload方法,悲剧发生了,虽然注销登录成功了(通过Ajax的方式),但是本页面并没有被filter拦截跳转到登录页面,但是其中引入的js,iframe却被filter拦住了,通过Fiddler2观察确实发送了很多次Login那个页面的请求,然后页面由于该加载的JS没过来,就在那儿不动了。这时只有点击刷新,才会真正的跳转到Login页面。
这是使用window.close的一个理由,否则就算location.href不成功,能在onload时自动跳转也没事,但可惜不行。
5 IE和Chrome弹两次这个问题,应该是通过将绑定事件放到onload,而不是直接写在<script>标签中。可能是这两个浏览器的某种机制使得他们会执行两次。
全部代码如下:
<script language='javascript'>
function getOs(){
if(navigator.userAgent.indexOf("MSIE")>0)return 1;//IE
if(isFirefox=navigator.userAgent.indexOf("Firefox")>0)return 2;//Firefox
if(isSafari=navigator.userAgent.indexOf("Chrome")>0)return 3;//Chrome
if(isSafari=navigator.userAgent.indexOf("Safari")>0)return 4;//Safari
if(isCamino=navigator.userAgent.indexOf("Camino")>0)return 5;//Camino
if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0)return 6;//Gecko
if(isOpera=navigator.userAgent.indexOf('Opera') >= 0) return 7;//Opera
//other...
return 0;
}
var quite=false;
function bindOnbeforeunload(){
quite=false;
window.onbeforeunload=checkLeave;
}
function unbindOnbeforeunload(){
quite=true;
window.onbeforeunload=null;
}
function checkLeave(){
return '您正在离开...';
}
window.onunload=function(){
try{
unbindOnbeforeunload();
}catch(e){
}
window.location.href='/Logout';
if(getOs()==3||getOs()==4){
var xmlHttp = false;
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
xmlHttp = false;
}
}
if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
xmlHttp = new XMLHttpRequest();
}
var url = "/Logout";
xmlHttp.open("POST", url, false);
// Send the request
xmlHttp.send(null);
window.open('', '_self', ''); //bug fix
window.close();
}
}
</script>
</head>
在HTML body中注册:
<body oncontextmenu="return false;" onload="javascript:return bindOnbeforeunload();" >
分享到:
相关推荐
下面是使用教程: 源码介绍 自己的域名总是被举报,变红? 搞一个遮罩(跳转浏览器提示)就OK了 迷惑性问题: 问:这个干什么用的。...当不再使用或者需要临时关闭跳转时,只需//注销该行代码即可。
主要介绍了javaweb用户注销后点击浏览器返回刷新页面重复登录问题的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
系统登录注销 适合一般的系统 登录与注销 只具有登录注销功能的哦
Windows系统多用户登录后远程断开,用户占用内存,需要注销远程断开用户. Windows系统多用户登录后远程断开,用户占用内存,需要注销远程断开用户. Windows系统多用户登录后远程断开,用户占用内存,需要注销远程...
浏览器有时候会卡死在桌面,用此软件能解决这类问题,但是因为是易语言写的,所以会误报
vc监控程序,如用户登录注销行为 监控用户登录
解决登录注销后退失效
本文档详细地介绍wincc flexible用户登录、注销及显示的操作步骤,简单明了易操作。
Android记住密码,线程自动登录,注销
Django注册、登录、注销示例 含源码
一旦用户注销并按浏览器后退按钮,如何阻止用户访问前一页
/// 强制页面过期,重新向服务器请求刷新页面 /// public static void ClearClientPageCache() { HttpContext.Current.Response.Buffer = true; HttpContext.Current.Response.Expires = 0; HttpContext....
域用户登陆自动注销脚本 域用户登陆自动注销脚本 域用户登陆自动注销脚本 域用户登陆自动注销脚本 域用户登陆自动注销脚本
一个简单模拟app注销登录的demo,轻松切换回登录首页
WinCC用户登录退出_用户注销_权限设置
可实现账号注册 修改密码 账号注销 登录功能 利用状态机制作 可用于不同场景登录
昆仑通态HMI权限自动注销方法,开发时可以直接拷贝使用
VB中注销, 重启和关闭计算机 VB中注销, 重启和关闭计算机VB中注销, 重启和关闭计算机VB中注销, 重启和关闭计算机VB中注销, 重启和关闭计算机
Windows XP启动并登录后立即自动注销解决方法
西门子官方技术文章