最近遇到一个bug,该bug的根源是一个挺奇怪的需求,问题很简单,是这样的:从一个页面登陆,登陆后进入到一个系统(嵌入到网页的applet),但是要求登陆后的页面要隐藏工具栏、导航栏。
咋一看很简单,但做的时候发现不对劲。浏览器页面的控制一般是用 javascript 中的内置对象window对象。下面是我的步骤:
1.如何隐藏导航栏、工具栏
开始想着在javrscript中将 windows.menubar=false 实在天真,window对象中,menubar、 locationbar、toobar等均是只读属性。想要设置这些属性,window对象只提供了一个接口:
window.open(URL,name,features,replace)
参数说明:
可以在features参数中设置以下表格的属性,只需把想要隐藏的属性设置为false或0 。(注:有些浏览器为了防止非法网站欺诈用户,是不允许隐藏掉地址栏的,在较新版本的chrome中,地址栏我隐藏不掉撒~)
channelmode=yes|no|1|0 | 是否使用剧院模式显示窗口。默认为 no。 |
directories=yes|no|1|0 | 是否添加目录按钮。默认为 yes。 |
fullscreen=yes|no|1|0 | 是否使用全屏模式显示浏览器。默认是 no。处于全屏模式的窗口必须同时处于剧院模式。 |
height=pixels | 窗口文档显示区的高度。以像素计。 |
left=pixels | 窗口的 x 坐标。以像素计。 |
location=yes|no|1|0 | 是否显示地址字段。默认是 yes。 |
menubar=yes|no|1|0 | 是否显示菜单栏。默认是 yes。 |
resizable=yes|no|1|0 | 窗口是否可调节尺寸。默认是 yes。 |
scrollbars=yes|no|1|0 | 是否显示滚动条。默认是 yes。 |
status=yes|no|1|0 | 是否添加状态栏。默认是 yes。 |
titlebar=yes|no|1|0 | 是否显示标题栏。默认是 yes。 |
toolbar=yes|no|1|0 | 是否显示浏览器的工具栏。默认是 yes。 |
top=pixels | 窗口的 y 坐标。 |
width=pixels | 窗口的文档显示区的宽度。以像素计。 |
但是open函数打开一个新的页面不满足我的需求,且划红线部分说明用 _parent、_self 等 指定自身页面的值付给name参数,features是不生效的。浏览器这么做应该是处于安全性的考虑,但对于我的这种特殊需求略显尴尬。无奈之下就用这种open的办法,在登录时弹出一个新的页面,但这就需要将之前的登录页面关闭(让用户多次登陆会疯掉的),这也是我们目前使用的办法。
2.js关闭页面
这个更简单,同样是windows对象,window.close()方法无疑。 这里查了好多好多资料后知道,主流浏览器为了用户的安全考虑,原则上只允许脚本关闭用window.open()方法打开的页面,比如说,用户在浏览器中点开一个tab,然后输入地址,回车,这样得到的页面是不允许直接用脚本关掉的。我们在网上看到的类似以下方法(其中self可以替换成window,是等价的):
self.opener=null;
self.open('', '_self');
self.close();
(注:FireFox浏览器需要在设置中开启允许脚本关闭浏览器的选项)
这些方法是利用浏览器的漏洞进行强行关闭的方法,即:将我们的页面伪装成用open()脚本打开的页面。上面的方法在IE11 和 Chrome36的较新版本 中是行不通的,后来我们用了open(location,'_self').close();
这种一看就是利用别人bug的方法,但效果不错哦,还屡试不爽,直到Chrome37的出现打了我的脸……
Chrome37中,上述代码会使页面无限跳转…是因为谷歌已经修复了这个bug。Chrome做得好,怪只怪我们的设计是有问题的…目前我逛遍了能找得到的论坛,还没找到新的方法。即便能找到,不排除chrome再次将新漏洞修复的可能,且随着更新IE,firefox也将漏洞补上也是早晚的事。
所以说,开发的时候看看标准文档就好了,不要想太多,跟着规范走,然后规范自己的设计。至于我们bug,我现在可能还在考虑用别的办法折中……