1. 程式人生 > >window.open()被瀏覽器攔截問題

window.open()被瀏覽器攔截問題

一、原因

瀏覽器為了維護使用者安全和體驗,在JS中直接使用window.open(url,"_blank")來開啟新的連結是會被攔截的,(window.open(url,”_self”)改變當前的視窗是可以生效的),通常專案需要在ajax非同步請求完成後來開啟新連結,下面提供幾種解決方案

二、解決方案

方案一、

建立一個a標籤,利用a標籤跳轉,能解決大多數瀏覽器相容問題,但是這種方法寫在ajax非同步請求完成後呼叫無效

function openWin(url) {
    var a = document.createElement("a"); //建立a標籤
    a.setAttribute("href", url);
    a.setAttribute("target", "_blank");
    document.body.appendChild(a);
    a.click(); //執行當前物件
}
openWin("./page/......");

方案二、

模擬form表單提交,能解決大多數瀏覽器相容問題,但是這種方法寫在ajax非同步請求完成後呼叫無效

var form = document.createElement('form');
form.action = '"./page/a.html?id=1';
form.target = '_blank';
form.method = 'POST';
document.body.appendChild(form);
form.submit();

方案三、

在ajax呼叫之前先開啟視窗,然後再設定新視窗的url來達到跳轉的效果,但是該方法如果ajax響應太慢,則會出現一個空白視窗,影響使用者體驗,所以建議給該新視窗增加提示“正在拼命載入中”,但是我覺得這個並不是最好的解決方案

//先在ajax函式之前開啟新視窗,後再載入url
$('#btn').click(function () {
    //開啟一個不被攔截的新視窗
    var win = window.open();
    win.document.body.innerHTML="正在拼命載入中......";
    $.ajax({
        url: 'a.com',
        success: function (url) {
            //修改新視窗的url
            win.location.href = url;
        }
    })
});

方案四、

把ajax非同步改成同步,該方法會阻塞瀏覽器執行導致卡頓,經過測試,就算改成同步,chrome還是會阻攔,Firefox不會阻攔

//先在ajax同步函式之後開啟新視窗
$('#btn').click(function () {
    $.ajax({
        url: 'a.com',
        async: false,  // 同步,意味著執行該ajax完成後,後續程式碼才繼續執行
        success: function (url) {
        }
    });

    //執行完ajax後再開啟新視窗
    window.open("./page/......", "_blank");
});

 

方案五、

 

把ajax執行完後,彈出一個彈出框提示使用者,由使用者確認點選開啟,這個方法目前感覺是最友好的

$('#btn').click(function () {
    $.ajax({
        url: 'a.com',
        success: function (url) {
            option.open({
                //type: 1,
                icon: 3,
                title: "支付",
                btn: ['立即檢視', '取消'],
                content: "檔案已經校驗成功,請檢視結果",
                btn1: function (index) {
                    option.closeAll();
                    window.open("./page/......");
                },
                btn2: function (index) {
                    option.closeAll();
                }
            });
        }
    });
});