解决window.open()被浏览器拦截的问题

一、问题描述

最近在做项目的时候碰到了使用window.open被浏览器拦截的情况,虽然在自己的环境可以对页面进行放行,但是对用户来说,不能要求用户都来通过拦截。何况当出现拦截时,很多用户根本不知道发生了啥,不知道在哪里看被拦截的页面。因此必须通过代码来解决这个问题!

以下是浏览器拦截示例:

二、问题分析

浏览器之所以拦截新开窗口是因为该操作并不是用户主动触发的,所以它认为这是不安全的就拦截了,即使 ajax 回调函数中模拟执行 click 或者 submit 等用户行为(trigger('click')),浏览器也会认为不是由用户主动触发的,因此不能被安全执行,所以被拦截。

三、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
  打开的窗体是否进行全屏显示

四、代码模拟

<!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>

五、解决方案在

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>

六、小结

上面方法,存在一个问题时,因为先打开了空白窗口,如果ajax请求失败(网络或业务逻辑问题)后, 新窗口中就不会有正常的结果体现,有可能造成用户疑惑。

一个解决办法是,当ajax出现问题时,可以考虑给出一个提示,如   newWindow.document.write("服务器处理异常");

甚至为了防止ajax响应时间过长,当窗口新建后,立即给出提示  newWindow.document.write("服务器正在处理中,请稍后");

后面如果ajax正常返回,则因为设置了location值,原来打印的信息会被新的页面信息覆盖。

七、思考

对于动态打开新窗口,没有特别完美的方法。具体还需根据特定的业务场景来采取相应的做法!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • js实现window.open不被拦截的解决方法汇总

    本文实例讲述了js实现window.open不被拦截的解决方法.分享给大家供大家参考.具体分析如下: 一.问题: 今天在处理页面ajax请求过程中,想实现请求后打开新页面,就想到通过 js window.open 来实现,但是最终都被浏览器拦截了. 二.分析: 在谷歌搜索有没有解决方法,有些说可以通过新建a标签,模拟点击来实现,但是测试发现都实现不了,照样被浏览器拦截. 最后找到了一个折中的办法,可以实现新页面打开,但是没有a标签的那种直接流量新页面的效果. 三.实现代码: 复制代码 代码如下:

  • window.open打开窗口被拦截的快速解决方法

    自己遇到的使用window.open打开新窗口被拦截的几种情况(使用的chrome浏览器,其他浏览器未测): 第一次:window.open(www.jb51.net),打开了新窗口,但是页面并没有加载出来,需要回车才能出来 解决方法:页面地址需要加上协议名称http://或者https:// 第二次:在ajax异步请求成功的回调函数中使用window.open方法,虽然加上了协议名称,但是,却并没有打开新窗口,在地址栏直接显示 被拦截 的字样 解决方法:有两种: 1.将ajax异步请求改为同步

  • window.open不被拦截的简单实现代码(推荐)

    实例如下: $("#last").click(function(){ var w=window.open(); setTimeout(function(){ w.location="http://www.jb51.net"; }, 1000); return false; }); window.open是javascript函数,该函数的作用是打开一个新窗口或这改变原来的窗口,如果你直接在js中调用window.open()函数去打开一个新窗口,浏览器会拦截你,那么

  • window.open关于浏览器拦截问题分析及解决方法

    window.open是javascript函数,该函数的作用是打开一个新窗口或这改变原来的窗口,不过一般用来的是打开新窗口,因为修改原来的网页地址,可以有另一个函数,那就是window.location,他可以重定向网页地址,使网页跳转到另一个页面. 我现在要说的是window.open函数的几个使用策略,一般情况下,如果你直接在js中调用window.open()函数去打开一个新窗口,浏览器会拦截你,认为你将弹出广告等用户不想得到的窗体,所以如果不想让浏览器拦截你,你可以将这个函数改为用户点

  • window.open不被拦截的实现代码

    复制代码 代码如下: $("#last").click(function(){ var w=window.open(); setTimeout(function(){ w.location="http://www.baidu.com"; }, 1000); return false; });

  • JS判断鼠标进入容器的方向与window.open新窗口被拦截的问题

    一.鼠标进入容器方向的判定 判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢? 首先想到的是:获取鼠标的位置,然后经过一大堆的if..else逻辑来确定.这样的做法比较繁琐,下面介绍两种比较方便的方法: 第一种方法,利用圆和反正切三角函数 如下图所示: 以div容器的中心点作为圆心,以高和宽的最小值作为直径画圆,将圆以[π/4,3π/4),[3π/4,5π/4),[5π/4,7π/4),[-π/4,π/4)划分为四个象限. 代码如下: $(".box").on(&quo

  • window.open被浏览器拦截后的自定义提示效果代码

    现在越来越多的浏览器有拦截弹出窗口的功能.广告弹出来给拦掉了就无所谓,要是客户在付款时给拦掉了可就不能乱算了. Gmail的"哎呀"算是经典,可是,前天心云给出了更帅的提示=.= 记得打开浏览器拦截后 测试一下,在线阅读器里不知道代码会不会给过滤..代码在下边,其实没什么技术含量滴.挖哈哈... 复制代码 代码如下: window._open=window.open;  window.open=function(sURL,sName,sFeatures,bReplace){    if

  • ajax请求成功后新开窗口window.open()被拦截解决方法

    问题: 前面开发项目时碰到一个问题,ajax 异步请求成功后需要新开窗口打开 url,使用的是 window.open() 方法,但是很可惜被浏览器给拦截了,怎么解决这个问题呢? 分析: 浏览器之所以拦截新开窗口是因为该操作并不是用户主动触发的,所以它认为这是不安全的就拦截了(不过如果是 _self 的话就不会有这个限制),即使 ajax 回调函数中模拟执行 click 或者 submit 等用户行为(trigger('click')),浏览器也会认为不是由用户主动触发的,因此不能被安全执行,所

  • Ajax请求响应中用window.open打开新窗口被拦截的解决方法

    一.问题描述 ajax 异步请求成功后需要新开窗口打开 url,使用的是 window.open() 方法,但是会被浏览器给拦截了,需要用户点下. 二.问题分析 浏览器之所以拦截新开窗口是因为该操作并不是用户主动触发的,所以它认为这是不安全的就拦截了,即使 ajax 回调函数中模拟执行 click 或者 submit 等用户行为(trigger('click')),浏览器也会认为不是由用户主动触发的,因此不能被安全执行,所以被拦截. 说明: 1.如果是在 <a href="javascri

  • 解决window.open()被浏览器拦截的问题

    一.问题描述 最近在做项目的时候碰到了使用window.open被浏览器拦截的情况,虽然在自己的环境可以对页面进行放行,但是对用户来说,不能要求用户都来通过拦截.何况当出现拦截时,很多用户根本不知道发生了啥,不知道在哪里看被拦截的页面.因此必须通过代码来解决这个问题! 以下是浏览器拦截示例: 二.问题分析 浏览器之所以拦截新开窗口是因为该操作并不是用户主动触发的,所以它认为这是不安全的就拦截了,即使 ajax 回调函数中模拟执行 click 或者 submit 等用户行为(trigger('cl

  • Ajax打开新窗口被浏览器拦截的两种解决办法

    最近在做支付时发现打开支付窗口时被浏览器拦截了,百度了一下才发现是因为打开窗口前用ajax验证是否能支付,所以不是用户主动触发的打开ixin窗口,浏览器认为这样不安全,所以给拦截了. 解决办法一 先开始打开一个空的新窗口,然后改变新窗口的url,具体代码为 var wd = window.open(); $.ajax({ type: "POST", dataType: "json", url: URL, data: {orderNo:orderNo}, succes

  • ajax回调打开新窗体防止浏览器拦截有效方法

    ajax回调打开新窗体防止浏览器拦截,就这么做! 问题剖析: function click_fun(){ window.open("www.baidu.com");//能打开 $.ajax({ 'url': '${pageContext.request.contextPath}/activity/savePrizes.htm', 'type': 'post', 'dataType': 'json', 'data': data, success: function (data) { wi

  • vue 路由跳转打开新窗口被浏览器拦截问题处理

    触发事件请求接口根据条件去判断在进行路由跳转:   <a @click="getGetMyPortfolioById(scope.row) ">查看</a>    getGetMyPortfolioById(vals) {      getMyPortfolioById({       }).then(response = >{          const routerdata = this.$router.resolve({             

  • window.close(); 关闭浏览器窗口js代码的总结介绍

    window.close(); 关闭浏览器窗口js代码的总结介绍 序号 关闭代码 需要确认 无任何作用 无需确认 测试 1 window.close() IE7 firefox,chrome, safari Opera Close 2 window.opener=null; window.open('','_self'); window.close();   firefox IE7,Opera, chrome,safari Close 3 window.open('','_self'); win

  • 模拟用户点击弹出新页面不会被浏览器拦截

    相信用过window.open的小伙伴们都遇到过被浏览器拦截导致页面无法弹出的情况:我们换下思路,什么情况下的新页面弹出才不会被浏览器拦截呢?比如<a />标签这种就不会:那么我们只要模拟下用户去主动点击这个<a />标签就不会有拦截的问题了. 先定义好HTML标签: 复制代码 代码如下: <a href="" id="alink" target="_blank" style="display: none&

随机推荐