探索浏览器页面关闭window.close()的使用详解


Posted in Javascript onAugust 21, 2020

说起来window.close(),这也是个“不太让人省心”的角色。因为浏览器兼容性千差万别,还对他有诸多限制。

使用语法:

window.close()

场景复现

昨天发现有人在csdn上传违禁文件,举报后来到了这个页面:

探索浏览器页面关闭window.close()的使用详解

里面那个按钮发现点击无效!
就。。。当时就挺尴尬的。

不过既然它说是【关闭】,当时就想到了这个堪称“漏洞百出”的close事件,F12打开控制台一看:果不其然

探索浏览器页面关闭window.close()的使用详解

看到这顿时就来了兴趣

探索过程和解决方案

为什么就突然来了兴趣呢?

首先,从这行代码中可以看出:这个页面不是通过 window.open() “打开”的 —— MDN文档中有说明:不是通过window.open()方法打开的窗口不能(直接)使用close进行关闭 (以前这条是针对Firefox的策略)

显然,csdn这位工程师也看过文档,所以想用【在本页面打开空白页,然后再强行关闭】的“取巧”方法。但我不知道当时是怎么测试的,还是说后来浏览器又加的限制,这行代码在本文所写时显然在所有浏览器上都不能执行!

现在让我通过语法解释一下上面的代码:

//摘自:MDN
var window = window.open(url,windowName,[windowFeatures]);

方法明确指出三个参数,第三个参数一般用于在“弹出框页面”处理长宽限制,和我们当前的问题没有关系,我们就不再考虑。

MDN对url参数进行了说明,这个参数可以是个路径,可以是个页面/图片/其他浏览器支持类型的资源的地址, 如果参数1你写空串,会在指定的上下文环境中创建一个空页面

我们看第二个参数windowName, 这个参数表示 你要指定资源在哪个窗口打开 ,如果你指定的窗口不存在,浏览器会创建一个新的窗口,并把这个窗口的window对象命名为windowName(可以通过window.name获取到),值得注意的是,这并不是这个窗口的【title】,当你在别处使用<a><form>标签时 可以将target属性的值写成 windowName 进行跳转,访问,为空时,一样创建新窗口。

通过此处的描述我们可以知道, windowName的值应该与target的值是相同的。

既然说到了target,正好上面csdn用的也是a标签,那我们就以a链接为例 (另一方面form不常用),为<a></a>添加 target 表示我要设置链接的打开方式

1._self —— 默认值,表示在当前上下文中打开,不需要写
2._blank表示我要新创建一个tab/window
3._parent 表示在其上级上下文环境中加载,没有上级时同_self
4._top表示在其顶级上下文环境中加载,没有时同_self

所以现在常用的写法就是:

  • 首先调用 window.open('', ‘_self') 方法 ,参数1置空 参数2写为_self 表示我们要在当前页面加载一个空;
  • 此时仿佛就是一个偷梁换柱的作用,通过加载进来一个空,将我们当前访问的页面变成window.open()打开的页面

这个时候 是不是就可以愉快地使用window.close()方法并成功关闭当前页面了?

可以!

笔者可以确切的告诉你,这种方法在本地测试绝大多数浏览器上都可以正常使用!
但偏偏在这里(本文开头所说实例)不行!

还有一点是:如果你在a标签的 href 中用了javascript:xxx;写事件,那就千万记得不能再加属性target!

就在我焦头烂额自我怀疑时,一师兄给我说了一个取巧的解决方案:about:blank

探索浏览器页面关闭window.close()的使用详解

也可以!但似乎这并不是最好的方法!!!

再回到上面的代码,我想了许久,莫不是 浏览器兼容性 的问题?
为此,我判断了IE、Firefox、和其余浏览器(因为据说Firefox仍然在这个问题上表现地尤为激烈):

// 兼容所有浏览器关闭页面方法
function ClosePage(){  
  if (navigator.userAgent.indexOf("MSIE") > 0){
    if (navigator.userAgent.indexOf("MSIE 6.0") > 0){
      window.opener = null;
      window.close();
    } else {
      window.open('', '_top');
      window.top.close();
    }
  } else if (navigator.userAgent.indexOf("Firefox") > 0) {
    window.location.href = 'about:blank';
  } else {
    window.opener = null;
    window.open('', '_self', '');
    window.close();
  }
}

用这个方法,在各个浏览器上找网页试了一下,效果还不错。
但…
很多浏览器上会有和上面about:blank一样的效果。

到这里我就纳闷了,到底是为什么?
可能是浏览器对close的实现策略导致的。不过还没等我纳闷完,另一个消息就来了:这段代码放到文首的那个页面依然不行。。。(更新:在google和Firefox的一些网站如三水点靠木也不能用!)

有点小懵,什么鬼?
csdn这里究竟用了什么导致“close事件不能执行”?

一些小建议和结尾

这一点我不得而知。我后来分析了整个页面,做了代码复现,断点调试。。。依然没能发现问题出在哪里。

不过我从一开始就觉得:这种方式——不论是“关闭页面”还是“打开一个空页面提示”,它的效果似乎都还不如“返回浏览器首页”好:

let historyLen = window.history.length;
window.history.go(-historyLen+1)

更新:
这里其实是有问题的,因为用户如果“主动”触发浏览器上面的“返回上一页”的按钮,那么window.history的length值并不会改变,当你再执行window.history.go()的时候就不会有响应了!(但是在本文场景下如果用户返回了上一页就不会有这个按钮了,此问题也就不存在)
笔者还想到了document.referrer,它是用于获取+改变“从哪里跳转过来的”路径的API,但是很不幸,我发现了一个很神奇的事情:document.referrer=""时,相当于“本页面” —— 也就是说,它会把上一个页面也变为当前页面!
这确实是很神奇的:因为go函数也实现了这个功能——相当于刷新当前页。

或者“返回网站首页”?

location.href="xxx" rel="external nofollow"

这样还能再宣传一波,何乐而不为?

到此这篇关于探索浏览器页面关闭window.close()的使用详解的文章就介绍到这了,更多相关浏览器页面关闭window.close()内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
一些Javascript的IE和Firefox(火狐)兼容性的问题总结及常用例子
May 21 Javascript
Jquery实现带动画效果的经典二级导航菜单
Mar 22 Javascript
jquery基础教程之数组使用详解
Mar 10 Javascript
JS使用eval解析JSON的注意事项分析
Nov 14 Javascript
js实现简单排列组合的方法
Jan 27 Javascript
关于JS 预解释的相关理解
Jun 28 Javascript
input框中的name和id的区别
Nov 16 Javascript
深入理解Vue 组件之间传值
Aug 16 Javascript
Vue+webpack项目配置便于维护的目录结构教程详解
Oct 14 Javascript
手淘flexible.js框架使用和源代码讲解小结
Oct 15 Javascript
JSON基本语法及与JavaScript的异同实例分析
Jan 04 Javascript
解决vue动态路由异步加载import组件,加载不到module的问题
Jul 26 Javascript
vue组件开发之tab切换组件使用详解
Aug 21 #Javascript
vue组件开发之slider组件使用详解
Aug 21 #Javascript
Vue左滑组件slider使用详解
Aug 21 #Javascript
vue实现移动端触屏拖拽功能
Aug 21 #Javascript
vue实现移动端拖动排序
Aug 21 #Javascript
微信小程序实现聊天室
Aug 21 #Javascript
vue实现折线图 可按时间查询
Aug 21 #Javascript
You might like
总集篇&特番节目先行播出!《SAO Alicization War of Underworld》第2季度TV动画4月25日放送!
2020/03/06 日漫
PHP去除数组中重复的元素并按键名排序函数
2008/08/18 PHP
使用配置类定义Codeigniter全局变量
2014/06/12 PHP
PHP用户管理中常用接口调用实例及解析(含源码)
2017/03/09 PHP
随机显示经典句子或诗歌的javascript脚本
2007/08/04 Javascript
Javascript 入门基础学习
2010/03/10 Javascript
JS控制弹出新页面窗口位置和大小的方法
2015/03/02 Javascript
JS获取iframe中marginHeight和marginWidth属性的方法
2015/04/01 Javascript
js实现文字垂直滚动和鼠标悬停效果
2015/12/31 Javascript
vuejs父子组件通信的问题
2017/01/11 Javascript
js以及jquery实现手风琴效果
2020/04/17 Javascript
Bootstrap学习笔记 轮播(Carousel)插件
2017/03/21 Javascript
详解Angular中的自定义服务Service、Provider以及Factory
2017/04/22 Javascript
[02:04]2018DOTA2亚洲邀请赛Secret赛前采访
2018/04/03 DOTA
Python Web框架Flask中使用七牛云存储实例
2015/02/08 Python
在Docker上部署Python的Flask框架的教程
2015/04/08 Python
Python使用bs4获取58同城城市分类的方法
2015/07/08 Python
Python基于scapy实现修改IP发送请求的方法示例
2017/07/08 Python
python模块之sys模块和序列化模块(实例讲解)
2017/09/13 Python
Python实现的自定义多线程多进程类示例
2018/03/23 Python
解决python中 f.write写入中文出错的问题
2018/10/31 Python
python实现取余操作的简单实例
2020/08/16 Python
协程Python 中实现多任务耗资源最小的方式
2020/10/19 Python
CSS3实现同时执行倾斜和旋转的动画效果
2016/10/27 HTML / CSS
HTML5实践-图片设置成灰度图
2012/11/12 HTML / CSS
全球知名旅游社区巴西站点:TripAdvisor巴西
2016/07/21 全球购物
雅诗兰黛(Estee Lauder)英国官方网站:世界顶级化妆品牌
2016/12/29 全球购物
特罗佩亚包官方网站:Tropea
2017/01/03 全球购物
TUMI澳大利亚网站:美国旅行箱包品牌
2017/03/27 全球购物
商务英语专业应届毕业生求职信
2013/10/28 职场文书
农村婚礼主持词
2014/03/13 职场文书
给男朋友的道歉短信
2015/05/12 职场文书
经典祝酒词大全
2015/08/12 职场文书
2019数学教师下学期工作总结
2019/06/27 职场文书
Nginx设置HTTPS的方法步骤 443证书配置方法
2022/03/21 Servers
Python使用Web框架Flask开发项目
2022/06/01 Python