探索浏览器页面关闭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 相关文章推荐
jQuery实现响应鼠标事件的图片透明效果【附demo源码下载】
Jun 16 Javascript
js检测离开或刷新页面时表单数据是否更改的方法
Aug 02 Javascript
Asp.Net之JS生成分页条的方法
Nov 23 Javascript
jQuery插件jqGrid动态获取列和列字段的方法
Mar 03 Javascript
完美解决axios跨域请求出错的问题
Feb 05 Javascript
JS构造一个html文本内容成文件流形式发送到后台
Jul 31 Javascript
原生JS实现旋转轮播图+文字内容切换效果【附源码】
Sep 29 Javascript
jquery插件开发模式实例详解
Jul 20 jQuery
angular异步验证防抖踩坑实录
Dec 01 Javascript
vue.js中使用微信扫一扫解决invalid signature问题(完美解决)
Apr 11 Javascript
vue实践---根据不同环境,自动转换请求的url地址操作
Sep 21 Javascript
nuxt 自定义 auth 中间件实现令牌的持久化操作
Nov 05 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
php图片处理:加水印、缩略图的实现(自定义函数:watermark、thumbnail)
2010/12/02 PHP
PHP生成静态HTML文档实现代码
2016/06/23 PHP
PHP代码加密的方法总结
2020/03/13 PHP
详解new function(){}和function(){}() 区别分析
2008/03/22 Javascript
jQuery 性能优化手册 推荐
2010/02/23 Javascript
浅析Prototype的模板类 Template
2011/12/07 Javascript
jqTransform form表单美化插件使用方法
2012/07/05 Javascript
jQuery 淡入淡出 png图在ie8下有黑色边框的解决方法
2013/03/05 Javascript
$(&quot;&quot;).click与onclick的区别示例介绍
2014/09/25 Javascript
node+express+jade制作简单网站指南
2014/11/26 Javascript
JS实现根据文件字节数返回文件大小的方法
2016/08/02 Javascript
js中less常用的方法小结
2017/08/09 Javascript
js实现京东秒杀倒计时功能
2019/01/21 Javascript
让 babel webpack vue 配置文件支持智能提示的方法
2019/06/22 Javascript
jQuery实现动态操作table行
2020/11/23 jQuery
vue3.0中友好使用antdv示例详解
2021/01/05 Vue.js
如何解决django配置settings时遇到Could not import settings 'conf.local'
2014/11/18 Python
总结python爬虫抓站的实用技巧
2016/08/09 Python
Python实现两个list对应元素相减操作示例
2017/06/09 Python
Python学习pygal绘制线图代码分享
2017/12/09 Python
python使用KNN算法手写体识别
2018/02/01 Python
Python即时网络爬虫项目启动说明详解
2018/02/23 Python
Python检测网络延迟的代码
2018/05/15 Python
python基于json文件实现的gearman任务自动重启代码实例
2019/08/13 Python
Python os模块常用方法和属性总结
2020/02/20 Python
解决python ThreadPoolExecutor 线程池中的异常捕获问题
2020/04/08 Python
python中读入二维csv格式的表格方法详解(以元组/列表形式表示)
2020/04/24 Python
中国高端鲜花第一品牌:roseonly(一生只送一人)
2017/02/12 全球购物
STAUD官方网站:洛杉矶独有的闲适风格
2019/04/11 全球购物
台湾屈臣氏网路商店:Watsons台湾
2020/12/29 全球购物
教育基金募捐倡议书
2014/05/14 职场文书
片区教研活动总结
2014/07/02 职场文书
试用期旷工辞退通知书
2015/04/17 职场文书
2016关于学习党章的心得体会
2016/01/15 职场文书
观看《筑梦中国》纪录片心得体会
2016/01/18 职场文书
搞笑Gif:这么白这么长的腿像极了一楼的女朋友
2022/03/21 杂记