在前端編寫中,可能會用到window.open
,<a target="_blank">
等方式來在新的tab打開url。但會發現,有些情況下新打開的tab頁會被chrome攔截了:
出現這種情況,很有可能是因為:這些調用不是由用戶行為(如:點擊)觸發的。
一種典型場景就是:點擊按鈕,觸發ajax請求,然后在ajax的回調中,打開新的tab頁。這里,打開新tab頁的操作是在回調的上下文中,並不在點擊事件中,嘗試打開tab頁就會被攔截。
以ajax導出pdf文件
為例,
$("#export_button").click(function(){ ... $.ajax({ url : 'generateExportPdfFileURl', ...... success : function(pdfFileUrl) { openInNewTab(pdfFileUrl); } ...... }); }); /*openInNewTab原始實現:被攔截*/ var openInNewTab = function(url) { var a = document.createElement("a"); a.setAttribute("href", url); a.setAttribute("target", "testNewWindow"); document.body.appendChild(a); a.click(); }
下面介紹通過增加用戶行為觸發和打開-更新多步操作兩種解決方法。
增加用戶行為觸發
ajax回調中打開新窗口被攔,是因為回調中上下文已不是用戶行為了,因此,可以通過在回調增加用戶提示,由用戶點擊確認觸發打開url:
/*openInNewTab實現:增加用戶行為觸發*/ var openInNewTab = function(url) { MsgUtil.alertPrompt("導出文件已生成",function () { var a = document.createElement("a"); a.setAttribute("href", url); a.setAttribute("target", "testNewWindow"); document.body.appendChild(a); a.click(); }, "打開"); } //MsgUtil.alertPrmpt是自行實現的提示彈窗: // alertPrmpt({prompt_text}, {callbackFn}, {button_text});
打開-更新多步操作
ajax回調中打開新窗口被攔,是因為回調中上下文已不是用戶行為了,另一種思路分步完成:在ajax之前打開一個新的window,然后在回調中更新window的location:
$("#export_button").click(function(){ ... openInNewTab("about:blank"); //先打開新窗口 $.ajax({ url : 'generateExportPdfFileURl', ...... success : function(pdfFileUrl) { updateNewWindowUrl(pdfFileUrl); } ...... }); }); //更新已打開窗口的url function updateNewWindowUrl(url) { var newWindow = window.open(null, 'testNewWindow'); newWindow.location.href = url; }
以上是以click為例驗證兩種方法,對於window.open打開新窗口,同理。
*:將ajax設置成同步調用,應該也可以,但不推薦。