程序小屋

记录生活中的点滴,分享、学习、创新

文章内容 1623753400

js打开新窗口被拦截问题

打开新窗口的方式主要有 window.open, a标签增加target="_blank"属性,form标签增加target="_blank"属性

用户直接点击的事件是不会被浏览器拦截的,如DOM里面的form标签和a标签,用户点击可以正常打开新窗口。

<a href="https://www.baidu.com" target="_blank">百度</a>

<form action="https://www.baidu.com" target="_blank">

    <input type="hidden" name="key" value="value">

    <button type="submit"> 提交</button>

</form>

1

2

3

4

5

6

如果是事件函数里面也是可以正常打开的(js调用该函数或者触发该事件还是会被拦截)

下面举例用的是window.open(), 但是对于js创建a标签和form标签模拟点击/提交的效果是一样的

下面可以打开:

<button onclick="openNewWin()">打开</button>

<script>

     function openNewWin(){

         var newWin = window.open('https://www.baidu.com');

         console.log(newWin);  // Window https://www.baidu.com/

         // 如果打开失败 newWin 为null

     }

</script>

1

2

3

4

5

6

7

8

只要不是ajax的回调函数,其他函数都可以正常打开(包括定时器的异步操作函数):

<button onclick="openNewWin()">打开</button>

<script>

     function openNewWin(){

         function open(url) {

             var newWin = window.open(url);

             console.log(newWin); // Window https://www.baidu.com/

         }

         open('https://www.baidu.com');

     }

</script>

1

2

3

4

5

6

7

8

9

10

<button onclick="openNewWin()">打开</button>

<script>

     function openNewWin(){

         setTimeout(() => {

             var newWin = window.open('https://www.baidu.com');

             console.log(newWin); // Window https://www.baidu.com/

         }, 2000);

     }

</script>

1

2

3

4

5

6

7

8

9

因此总结js打开新窗口会被拦截的情况有三种,一是非用户触发事件的函数内打开新窗口,二是在ajax的回调函数里面打开新窗口,第三是一次打开多个新窗口,除了第一个,其他都会被拦截。

重点

了解到上面的情况后,解决方法就确定下来了,在用户点击的地方先打开新窗口,然后重定向路由过去(对于新窗口链接确定的情况,如果不确定,如通过form表单post数据到新页面的形式现在暂无解决方案)

<button onclick="openNewWin()">打开</button>

<script>

     function openNewWin(){

         var newWin = window.open();

         setTimeout(() => {

             newWin.location.href = 'https://www.baidu.com';

             // newWin.close();

         }, 2000);

     }

</script>

1

2

3

4

5

6

7

8

9

10

我这里的实际业务主要是通过form表单post数据打印pdf,因此解决方法是不新窗口打开,直接让接口返回文件流下载,如此也不会导致页面的刷新。

var pdfDownload = function (template, header, footer, size, filename, datas, as) {

    constant.template_name = template ? template : constant.template_name;

    constant.header_template = header ? header : constant.header_template;

    constant.footer_template = footer ? footer : constant.footer_template;

    constant.page_size = size ? size : constant.page_size;

    constant.filename = filename ? filename : constant.filename;

    constant.datas = datas ? datas : constant.datas;

    constant.as = as ? as : constant.as;

    var tempForm = document.createElement('form');

    tempForm.style.display = "none";

    tempForm.method = "POST";

    tempForm.action = "/pdfprint";

    tempForm.target = !constant.filename ? "_blank" : '';

    tempForm = angular.element(tempForm);

    constant.forEach(function (v, k) {

        if (v) {

            var hiddenInput = document.createElement("input");

            hiddenInput.name = k;

            hiddenInput.value = v;

            hiddenInput.type = "hidden";

            tempForm.append(hiddenInput);

        }

    });

    angular.element('body').append(tempForm);

    tempForm.submit();

    tempForm.remove();

}


*