解決window.open()被瀏覽器攔截的問題
一、問題描述
最近在做項目的時候碰到了使用window.open被瀏覽器攔截的情況,雖然在自己的環(huán)境可以對頁面進(jìn)行放行,但是對用戶來說,不能要求用戶都來通過攔截。何況當(dāng)出現(xiàn)攔截時,很多用戶根本不知道發(fā)生了啥,不知道在哪里看被攔截的頁面。因此必須通過代碼來解決這個問題!
以下是瀏覽器攔截示例:
二、問題分析
瀏覽器之所以攔截新開窗口是因為該操作并不是用戶主動觸發(fā)的,所以它認(rèn)為這是不安全的就攔截了,即使 ajax 回調(diào)函數(shù)中模擬執(zhí)行 click 或者 submit 等用戶行為(trigger('click')),瀏覽器也會認(rèn)為不是由用戶主動觸發(fā)的,因此不能被安全執(zhí)行,所以被攔截。
三、window.open()語法
window.open(url, name, features, replace)
Arguments - 參數(shù) url
可選字符串參數(shù),指向要在新窗口中顯示的文檔的URL。如果省略該參數(shù),或者參數(shù)為空字符串,新窗口不會顯示文檔。
name
可選字符串參數(shù),該參數(shù)可以設(shè)置新窗口的名稱。
相同name的窗口只能創(chuàng)建一個,要想創(chuàng)建多個窗口則name不能相同。
features
可選字符串參數(shù),該參數(shù)用于設(shè)定新窗口的功能。因為該參數(shù)是可選的,如果沒有指定該參數(shù),新窗口有所有的標(biāo)準(zhǔn)功能。
replace
可選布爾參數(shù),設(shè)置新窗口中的操作歷史的保存方式。
true - 創(chuàng)建新歷史記錄
false - 替換舊的歷史記錄
Returns - 返回值
一個根據(jù)name參數(shù)對新創(chuàng)建的或已存在的窗口對象的引用。
Description - 描述
open()方法可以查找一個已經(jīng)存在的或者新建的瀏覽器窗口。如果name參數(shù)指定了一個已經(jīng)存在的劉瀏覽器窗口,則返回對該窗口的引用。返回的窗口中將顯示URL中指定的文檔,但是features參數(shù)會被忽略。open()方法是JavaScript中唯一通過名稱獲得瀏覽器窗口引用的途徑。
如果沒有指定name參數(shù),或者不存在name參數(shù)指定的名稱的窗口,open()方法將創(chuàng)建一個新的瀏覽器窗口。
name參數(shù)用于指定新窗口的名稱,該名稱必須由字母、數(shù)字和下劃線字符組成。它可以被HTML文檔中的<a>標(biāo)記或<form>標(biāo)記指向。
當(dāng)你使用window.open()方法加載一個新的文檔到一個已經(jīng)存在了命名的窗口中時,你可以通過replace參數(shù)設(shè)置歷史記錄的保存方式.。如果該參數(shù)是true, 新文檔的歷史記錄將取代舊文檔的歷史記錄。 如果該參數(shù)為false或這沒有指定該參數(shù),新的文件在窗口的瀏覽歷史記錄中將建立自己的條目。該參數(shù)提供了location.replace()相同功能的方式。
不要把"Window.open( ) "和"Document.open( )"混淆;這是兩個完全不一樣的方法。為了讓代碼更明晰,你可以用"Window.open( )"代替 "open( )"。作為HTML屬性定義事件處理程序時, "open( )" 一般被解釋為"Document.open( )",所以在這種情況下,你必須使用"Window.open( )"。
Window Features - 窗口特性
feature參數(shù)是一個用逗號分隔的功能列表。如果該參數(shù)為空或者沒有指定該參數(shù),新的窗口將擁有所有的功能。另一方面, 如果feature參數(shù)只指定了某一項或某幾項功能,那么其他沒有被指定的功能將不會出現(xiàn)在新的窗口中。該字符串不能包含任何空格或其它空字符串。
列表中的每個元素的格式:功能[=值]
對于絕大多數(shù)的功能來說,它們的值一般都是yes或no。對這些功能,等號和值都可以省略不寫。 對于 width和height特性,必須給它們指定一個以像素為單位的值。
一下是一些普遍支持的功能和它們的含義:
height
設(shè)定窗口顯示區(qū)域的像素寬度
left
瀏覽器窗口距離屏幕左邊的距離
location
指明地址欄在新窗口中是否可見
menubar
指明菜單欄在新窗口中是否可見
resizable
指明新窗口是否可以調(diào)整大小
scrollbars
指明滾動欄在新窗口中是否可見
status
指明狀態(tài)欄在新窗口中是否可見
toolbar
指明工具欄在新窗口中是否可見
top
設(shè)定新窗口距屏幕上方的距離
width
設(shè)定窗口顯示區(qū)域的像素寬度
alwaysLowered
指定窗口隱藏在所有窗口之下
alwaysRaised
指定窗口浮在所有窗口之上
dependent
指定打開的窗口為父窗口的一個子窗口。并隨父窗口的關(guān)閉而關(guān)閉
directions
指定Navigator 2和3的目錄欄是否在新窗口中可見
hotkeys
在沒有菜單欄的新窗口設(shè)置安全退出熱鍵
innerHeight
設(shè)置新窗口中文檔的像素高度
innerWidth
設(shè)置新窗口中文檔的像素寬度
menubar
指明菜單欄在新窗口中是否可見
outerHeight
設(shè)定窗口(包括裝飾邊框)的像素高度
outerWidth
設(shè)定窗口(包括裝飾邊框)的像素寬度
screenX
設(shè)定新窗口離屏幕邊界的像素長度
screenY
設(shè)定新窗口離屏幕上邊界的像素長度
titlebar
指明菜單題目欄在新窗口是否可見
z-look
在文檔中包含各個 <pplet>標(biāo)簽的數(shù)組
fullscreen
打開的窗體是否進(jìn)行全屏顯示
四、代碼模擬
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>測試彈框攔截</title> <script> window.open("http://www.cnblogs.com/chenyablog/","測試彈框","top=nInt,left=nInt,width=nInt,height=nInt,location=yes,menubar=no,resizable=yes,scrollbars=yes,status=no,toolbar=no"); </script> </head> <body> <h1>測試彈框攔截</h1> </body> </html>
五、解決方案在
ajax請求之前,先用window.open 打開一個空白窗口,然后在ajax的響應(yīng)函數(shù)中設(shè)置該窗口的location屬性為新的url。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>測試彈框攔截</title> <script> async displayProjectileFrame (type) { const title = '測試彈框攔截' // 先打開一個窗口 let newWindow = window.open() //給新窗口設(shè)置標(biāo)題 newWindow.document.title = title try { const base = 'xxxxxxxxxx' // 這里是模擬ajax,不同使用場景需要有所變化 const openUrl = await this.$axios.$get('/xxx/xxxx', { params: { base } }) if (openUrl) { // 重定向 newWindow.location = openUrl } } catch (e) { this.$axiosError(e) } } </script> </head> <body> <h1>測試彈框攔截</h1> </body> </html>
六、小結(jié)
上面方法,存在一個問題時,因為先打開了空白窗口,如果ajax請求失?。ňW(wǎng)絡(luò)或業(yè)務(wù)邏輯問題)后, 新窗口中就不會有正常的結(jié)果體現(xiàn),有可能造成用戶疑惑。
一個解決辦法是,當(dāng)ajax出現(xiàn)問題時,可以考慮給出一個提示,如 newWindow.document.write("服務(wù)器處理異常");
甚至為了防止ajax響應(yīng)時間過長,當(dāng)窗口新建后,立即給出提示 newWindow.document.write("服務(wù)器正在處理中,請稍后");
后面如果ajax正常返回,則因為設(shè)置了location值,原來打印的信息會被新的頁面信息覆蓋。
七、思考
對于動態(tài)打開新窗口,沒有特別完美的方法。具體還需根據(jù)特定的業(yè)務(wù)場景來采取相應(yīng)的做法!
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
AjaxFileUpload.js實現(xiàn)異步上傳文件功能
這篇文章主要為大家詳細(xì)介紹了AjaxFileUpload.js實現(xiàn)異步上傳文件功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-04-04JavaScript設(shè)計模式之職責(zé)鏈模式應(yīng)用示例
這篇文章主要介紹了JavaScript設(shè)計模式之職責(zé)鏈模式,結(jié)合實例形式分析了javascript責(zé)任鏈模式的概念、原理、使用方法及相關(guān)操作注意事項,需要的朋友可以參考下2018-08-08JavaScript面向?qū)ο髮崿F(xiàn)貪吃蛇游戲
這篇文章主要為大家詳細(xì)介紹了JavaScript面向?qū)ο髮崿F(xiàn)貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04詳解MVC如何使用開源分頁插件(shenniu.pager.js)
本文主要分享了shenniu.pager.js整個插件內(nèi)容,不多且清晰。具有很好的參考價值,需要的朋友一起來看下吧2016-12-12淺析Javascript中雙等號(==)隱性轉(zhuǎn)換機(jī)制
這篇文章給大家詳細(xì)介紹了javascript中雙等號(==)隱性轉(zhuǎn)換機(jī)制,非常不錯,具有參考借鑒價值,需要的朋友參考下吧2017-10-10javascript實現(xiàn)checkbox全選的代碼
本文給大家分享的是js實現(xiàn)checkbox的全選的代碼,在網(wǎng)頁制作中很常用的js代碼,供大家學(xué)習(xí)參考。2015-04-04