window.open 打開新窗口被攔截的解決方案

最近公司開發的一個項目,平凡用到下載各類類型的文件,可是例如.txt,.jpg,.pdf格式的文件呢瀏覽器會在當前窗口直接打開,影響用戶體驗,嘗試各類方案和百度總結一下幾點;javascript


原理:

當window.open爲用戶觸發事件內部或者加載時,不會被攔截,一旦將彈出代碼移動到ajax或者一段異步代碼內部,立刻就出現被攔截的表現了(瀏覽器認爲這多是一個廣告,不是一個用戶但願看到的頁面)

經常使用辦法頁面打開方式

  1. 超連接<a href="https://www.baidu.com" title="">Welcome</a>

    等效於js代碼java

    window.location.href="https://www.baidu.com"; //在同當前窗口中打開窗口ajax

  2. 超連接<a href="https://www.baidu.com/" title=""target="_blank">Welcome</a>

    等效於js代碼json

    window.open("https://www.baidu.com/"); //在另外新建窗口中打開窗口瀏覽器

  3. 關閉新窗口:this.window.opener =null; window.close();

解決方案:

  • 使用a標籤替代:

給出以下函數,將此函數綁定到click的事件回調中,就能夠避免大部分瀏覽器對窗口彈出 的攔截:app

function newWin(url, id) {  
    var a = document.createElement(‘a‘);  
    a.setAttribute(‘href‘, url);  
    a.setAttribute(‘target‘, ‘_blank‘);  
    a.setAttribute(‘id‘, id);  
    // 防止反覆添加  
    if(!document.getElementById(id)) {                       
        document.body.appendChild(a);  
    }  
     a.click();  
}  

function openUrl(url) {
    var a = $('<a href="'+url+'" target="_blank"></a>')[0];
    var e = document.createEvent('MouseEvents');
    e.initEvent('click', true, true);
    a.dispatchEvent(e);
}

//調用方法newWin(url,'bbb') / openUrl(url)
//原理都是經過建立一個a標籤對象,經過裏面自帶的target執行跳轉
  • 在超連接里加入onclick事件,如:

//這樣用戶點擊這個超連接,瀏覽器會認爲它是打開一個新的連接,因此就不會攔 截。異步

<a href="javascript:void(0)" onclick="window.open()"></a>
  • 使用 setTimeout 包裝一下,也能夠防止被瀏覽器攔截。

//注意這裏的超時時間不能過短,不然也會被攔截。async

setTimeout('window.open(url);', 500);
  • 咱們會遇到想要彈出一個窗口,但是倒是在onckick事件執行後,纔去彈出來的,這時就會被瀏覽器攔截,咱們能夠經過下面的方法來避免

//先用window.open打開一個窗口,而後修改地址。如:函數

var tempwindow=window.open('_blank');

呵呵噠,你覺得這樣就完事了?大錯特錯了,以上辦法也就是在已聲明url下有效,若是異步ajax請求獲取下載路徑呢?

解決1:post

click: () => {
    var tempwindow=window.open();//先打開臨時窗體,因爲是點擊事件內觸發,不會被攔截 
    this.$http.get(url+id,
    {emulateJSON: true}
    ).then(response => {
        let resd = response.data;
        if(resd.code==0){
             tempwindow.location.href = resd.result//當回調的時候更改臨時窗體的路徑
        }
        else{
            tempwindow.close()//回調發現無需打開窗體時能夠關閉以前的臨時窗體
            this.$Message.error(resd.message)
        }
   }, response => {
        tempwindow.close()//回調發現無需打開窗體時能夠關閉以前的臨時窗體
        console.log('error:', response) //for debug
    });
}

解決2:

click: () => {
    var flag = false;   
    $.ajax({   
        'url': url+id,   
        'type': 'post',   
        'dataType': 'json',   
        'data': data,   
        'async':false,//同步請求   
        success: function (data) {   
           $("#a").attr("href","www.baidu.com");//當回調的時候更改頁面上或建立的某個a標籤的href   
           flag = true;//更改標誌   
        },   
        error:function(){   
          
        }   
   });   
   if(flag){   
       $("#a")[0].click();//href屬性更改後模擬點擊   
   }  
}
相關文章
相關標籤/搜索