window.open()被浏览器拦截问题汇总

1、问题描述html

最近在作项目的时候碰到了使用window.open被浏览器拦截的状况,虽然在本身的环境能够对页面进行放行,可是对用户来讲,不能要求用户都来经过拦截。况且当出现拦截时,不少用户根本不知道发生了啥,不知道在哪里看被拦截的页面。所以必须经过代码来解决这个问题!ios

如下是浏览器拦截示例:ajax

 

 

 

 

 2、问题分析 
浏览器之因此拦截新开窗口是由于该操做并非用户主动触发的,因此它认为这是不安全的就拦截了,即便 ajax 回调函数中模拟执行 click 或者 submit 等用户行为(trigger('click')),浏览器也会认为不是由用户主动触发的,所以不能被安全执行,因此被拦截。
 
3、window.open()语法
window.open(url, name, features, replace)   Arguments - 参数  url   可选字符串参数,指向要在新窗口中显示的文档的URL。若是省略该参数,或者参数为空字符串,新窗口不会显示文档。   name   可选字符串参数,该参数能够设置新窗口的名称。   相同name的窗口只能建立一个,要想建立多个窗口则name不能相同。   features   可选字符串参数,该参数用于设定新窗口的功能。由于该参数是可选的,若是没有指定该参数,新窗口有全部的标准功能。   replace   可选布尔参数,设置新窗口中的操做历史的保存方式。   true - 建立新历史记录   false - 替换旧的历史记录 Returns - 返回值   一个根据name参数对新建立的或已存在的窗口对象的引用。 Description - 描述   open()方法能够查找一个已经存在的或者新建的浏览器窗口。若是name参数指定了一个已经存在的刘浏览器窗口,则返回对该窗口的引用。返回的窗口中将显示URL中指定的文档,可是features参数会被忽略。open()方法是JavaScript中惟一经过名称得到浏览器窗口引用的途径。   若是没有指定name参数,或者不存在name参数指定的名称的窗口,open()方法将建立一个新的浏览器窗口。   name参数用于指定新窗口的名称,该名称必须由字母、数字和下划线字符组成。它能够被HTML文档中的<a>标记或<form>标记指向。   当你使用window.open()方法加载一个新的文档到一个已经存在了命名的窗口中时,你能够经过replace参数设置历史记录的保存方式.。若是该参数是true, 新文档的历史记录将取代旧文档的历史记录。 若是该参数为false或这没有指定该参数,新的文件在窗口的浏览历史记录中将创建本身的条目。该参数提供了location.replace()相同功能的方式。   不要把"Window.open( ) ""Document.open( )"混淆;这是两个彻底不同的方法。为了让代码更明晰,你能够用"Window.open( )"代替 "open( )"。做为HTML属性定义事件处理程序时, "open( )" 通常被解释为"Document.open( )",因此在这种状况下,你必须使用"Window.open( )"。 Window Features - 窗口特性   feature参数是一个用逗号分隔的功能列表。若是该参数为空或者没有指定该参数,新的窗口将拥有全部的功能。另外一方面, 若是feature参数只指定了某一项或某几项功能,那么其余没有被指定的功能将不会出如今新的窗口中。该字符串不能包含任何空格或其它空字符串。   列表中的每一个元素的格式:功能[=值]   对于绝大多数的功能来讲,它们的值通常都是yes或no。对这些功能,等号和值均可以省略不写。 对于 width和height特性,必须给它们指定一个以像素为单位的值。   一下是一些广泛支持的功能和它们的含义:   height   设定窗口显示区域的像素宽度   left   浏览器窗口距离屏幕左边的距离   location   指明地址栏在新窗口中是否可见   menubar   指明菜单栏在新窗口中是否可见   resizable   指明新窗口是否能够调整大小   scrollbars   指明滚动栏在新窗口中是否可见   status   指明状态栏在新窗口中是否可见   toolbar   指明工具栏在新窗口中是否可见   top   设定新窗口距屏幕上方的距离   width   设定窗口显示区域的像素宽度   alwaysLowered   指定窗口隐藏在全部窗口之下   alwaysRaised   指定窗口浮在全部窗口之上   dependent   指定打开的窗口为父窗口的一个子窗口。并随父窗口的关闭而关闭   directions   指定Navigator 2和3的目录栏是否在新窗口中可见   hotkeys   在没有菜单栏的新窗口设置安全退出热键   innerHeight   设置新窗口中文档的像素高度   innerWidth   设置新窗口中文档的像素宽度   menubar   指明菜单栏在新窗口中是否可见   outerHeight   设定窗口(包括装饰边框)的像素高度   outerWidth   设定窗口(包括装饰边框)的像素宽度   screenX   设定新窗口离屏幕边界的像素长度   screenY   设定新窗口离屏幕上边界的像素长度   titlebar   指明菜单题目栏在新窗口是否可见   z-look   在文档中包含各个 <pplet>标签的数组   fullscreen   打开的窗体是否进行全屏显示

 4、代码模拟axios

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>测试弹框拦截</title>
  <script>
    window.open("http://www.cnblogs.com/chenyablog/","测试弹框","top=nInt,left=nInt,width=nInt,height=nInt,location=yes,menubar=no,resizable=yes,scrollbars=yes,status=no,toolbar=no");
  </script>
</head>
<body>
   <h1>测试弹框拦截</h1>
</body>
</html>
 
 5、解决方案
在ajax请求以前,先用window.open 打开一个空白窗口,而后在ajax的响应函数中设置该窗口的location属性为新的url。
 
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>测试弹框拦截</title>
  <script>
    async displayProjectileFrame (type) {
      const title = '测试弹框拦截'
      // 先打开一个窗口
      let newWindow = window.open()       //给新窗口设置标题
      newWindow.document.title = title
      try {
        const base = 'xxxxxxxxxx'
          // 这里是模拟ajax,不一样使用场景须要有所变化
        const openUrl = await this.$axios.$get('/xxx/xxxx', {
          params: {
            base
          }
        })
        if (openUrl) {
          // 重定向
          newWindow.location = openUrl
        }
      } catch (e) {
        this.$axiosError(e)
      }
    }
  </script>
</head>
<body>
   <h1>测试弹框拦截</h1>
</body>
</html>

 

6、小结数组

上面方法,存在一个问题时,由于先打开了空白窗口,若是ajax请求失败(网络或业务逻辑问题)后, 新窗口中就不会有正常的结果体现,有可能形成用户疑惑。 一个解决办法是,当ajax出现问题时,能够考虑给出一个提示,如 newWindow.document.write("服务器处理异常"); 甚至为了防止ajax响应时间过长,当窗口新建后,当即给出提示 newWindow.document.write("服务器正在处理中,请稍后"); 后面若是ajax正常返回,则由于设置了location值,原来打印的信息会被新的页面信息覆盖。

7、思考浏览器

对于动态打开新窗口,没有特别完美的方法。具体还需根据特定的业务场景来采起相应的作法!
相关文章
相关标签/搜索