window.open 被浏览器拦截问题

window.open 被浏览器拦截问题

window.open() 的作用是创建一个新的浏览器窗口用来打开相关的资源,这是一个原生的 Javascript API 接口

  • 有关 window.open() 的基本使用可以参考 mozilla 提供的 API文档:window.open

大部分现代的浏览器(泛指 Chrome / Firefox / IE 10+ / Safari)都默认开启了阻止弹出窗口的策略,原因是 window.open 被广告商滥用,严重影响用户的使用。这个阻止弹出窗口的操作,并不是直接封杀 windw.open(),而是会根据用户的行为来判断这次 window.open() 是否属于流氓操作

如果是由用户触发的动作所引起的 window.open 就不会被浏览器所阻止,比如写在 onclick 这些事件 handler 里的,但如果是代码自己触发的就会被阻止

问题:

  • 如果是用户点击后,我们的程序需要运行一些代码然后才执行 window.open() ,这种情况是否会被阻止呢?

答案:

  • 我们用Chrome浏览器来测试,当延迟 100 毫秒的时候,Chrome 会让窗口弹出,但是当延迟 2000 毫秒(即 2s)时这个操作会被阻止。经过多次试验,我发现这个临界值是 1000 毫秒。1000 毫秒的时候允许弹出框, 1001 毫秒的时候被阻止

在 Safari / Chrome / Firefox下测试,都是 1001 毫秒的时候被阻止

  • 整体来说,Safari / Chrome / Firefox (桌面版) , 对于用户点击事件后的 window.open() 有 1s
    的延迟容忍度,如果是由用户点击触发的 window.open() 代码前面,可以加上少量简单的逻辑代码来运行,但请控制在执行时间为 1s 内

标题可能会起到效果的解决方案

1.创建一个a标签,利用a标签跳转,能解决大多数浏览器兼容问题,但是这种方法写在ajax异步请求完成后调用无效

function open(url) {
    var a = document.createElement("a"); //创建a标签
    a.setAttribute("href", url);
    a.setAttribute("target", "_blank");
    document.body.appendChild(a);
    a.click(); //执行当前对象
}
open(url);

2.模拟form表单提交,能解决大多数浏览器兼容问题,但是这种方法写在ajax异步请求完成后调用无效

var form = document.createElement('form');
form.action = 接口地址;
form.target = '_blank';
form.method = 'POST';
document.body.appendChild(form);
form.submit();

3.在ajax调用之前先打开窗口,然后再设置新窗口的url来达到跳转的效果,但是该方法如果ajax响应太慢,则会出现一个空白窗口,影响用户体验,所以建议给该新窗口增加提示“正在拼命加载中”,但是我觉得这个并不是最好的解决方案

//先在ajax函数之前打开新窗口,后再加载url
function () {
    //打开一个不被拦截的新窗口
    var win = window.open();
    win.document.body.innerHTML="正在拼命加载中......";
    $.ajax({
        url: 'xxx',
        success: function (url) {
            //修改新窗口的url
            win.location.href = url;
        }
    })
});

4.把ajax异步改成同步,该方法会阻塞浏览器运行导致卡顿,经过测试,就算改成同步,chrome还是会阻拦,Firefox不会阻拦

//先在ajax同步函数之后打开新窗口
function () {
    $.ajax({
        url: 'a.com',
        async: false,  // 同步,意味着执行该ajax完成后,后续代码才继续运行
        success: function (url) {
        }
    });
    //执行完ajax后再打开新窗口
    window.open(url, "_blank");
});

5.把ajax执行完后,弹出一个弹出框提示用户,由用户确认点击打开,这个方法目前感觉是最友好的
jQuery方式

$('#btn').click(function () {
    $.ajax({
        url: 'xxx',
        success: function (url) {
            option.open({
                icon: 3,
                title: "支付",
                btn: ['立即查看', '取消'],
                content: "文件已经校验成功,请查看结果",
                btn1: function (index) {
                    option.closeAll();
                    window.open("./page/......");
                },
                btn2: function (index) {
                    option.closeAll();
                }
            });
        }
    });
});

vue方式

open(url) {
  this.$confirm('此操作将会打开新窗口, 是否继续?', '提示', {
     confirmButtonText: '确定',
     cancelButtonText: '取消',
     type: 'warning'
   }).then(() => {
     window.open(url);
   }).catch(() => {
     this.$message({
       type: 'info',
       message: '已取消打开新窗口!'
     });
   });
 },
onlineReviewClickNew(id) {
  // 设置遮罩层
  const loading = this.$loading({
     lock: true,
     text: '正在加载',
     spinner: 'el-icon-loading',
     background: 'rgba(0, 0, 0, 0.7)'
   });
   let url = url;
   fetch(url,{
     method: "get",
     headers: {
      // 如果需要登录权限认证,请求头在这里添加
     }
   }).then((res) => res.blob())
   .then(data => {
     loading.close();
     this.open(encodeURIComponent(window.URL.createObjectURL(data))});
   }).catch(error => alert(error.message));
 },
 / 此处模拟的是在线预览PDF,前台接收后台返回的流数据经过处理之后通过pdf.js插件在线打开
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用`window.open`方法打开一个新窗口时,有时候浏览器拦截这个操作,阻止新窗口的打开。这是因为浏览器内置了一些安全机制,旨在防止恶意弹窗和广告等不受用户控制的行为。 浏览器拦截`window.open`的主要原因可能包括以下几点: 1. 弹窗拦截浏览器拦截那些未经用户交互而直接打开的新窗口,以防止恶意网站滥用弹窗功能。这是为了保护用户免受不必要的干扰和潜在的安全风险。 2. 广告拦截:一些浏览器会自动屏蔽那些被认定为广告的弹窗。这些浏览器会根据广告过滤规则或者用户自定义的设置来判断哪些弹窗是广告,并将其拦截。 3. 浏览器设置:用户可能在浏览器的设置中主动选择了阻止弹窗的选项,这样浏览器就会拦截`window.open`方法打开的新窗口。 如果你希望绕过浏览器拦截,可以尝试以下方法: 1. 触发`window.open`方法的操作必须是由用户主动触发的,例如在点击事件中调用`window.open`方法。这样可以避免被浏览器拦截。 2. 检查浏览器的弹窗拦截设置,确保它没有被启用或者将你的网站添加到白名单中。 3. 使用浏览器提供的替代方法,例如`window.location.href`来打开新的URL,或者使用`<a>`标签的`target="_blank"`属性来实现类似的功能。 请注意,绕过浏览器拦截机制可能会违反用户的期望和浏览器的安全策略。因此,在进行任何操作之前,请确保你的意图是合法和符合用户体验的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值