解決window.open()被瀏覽器攔截的問題
一、問題描述
最近在做項(xiàng)目的時(shí)候碰到了使用window.open被瀏覽器攔截的情況,雖然在自己的環(huán)境可以對(duì)頁面進(jìn)行放行,但是對(duì)用戶來說,不能要求用戶都來通過攔截。何況當(dāng)出現(xiàn)攔截時(shí),很多用戶根本不知道發(fā)生了啥,不知道在哪里看被攔截的頁面。因此必須通過代碼來解決這個(gè)問題!
以下是瀏覽器攔截示例:




二、問題分析
瀏覽器之所以攔截新開窗口是因?yàn)樵摬僮鞑⒉皇怯脩糁鲃?dòng)觸發(fā)的,所以它認(rèn)為這是不安全的就攔截了,即使 ajax 回調(diào)函數(shù)中模擬執(zhí)行 click 或者 submit 等用戶行為(trigger('click')),瀏覽器也會(huì)認(rèn)為不是由用戶主動(dòng)觸發(fā)的,因此不能被安全執(zhí)行,所以被攔截。
三、window.open()語法
window.open(url, name, features, replace)
Arguments - 參數(shù) url
可選字符串參數(shù),指向要在新窗口中顯示的文檔的URL。如果省略該參數(shù),或者參數(shù)為空字符串,新窗口不會(huì)顯示文檔。
name
可選字符串參數(shù),該參數(shù)可以設(shè)置新窗口的名稱。
相同name的窗口只能創(chuàng)建一個(gè),要想創(chuàng)建多個(gè)窗口則name不能相同。
features
可選字符串參數(shù),該參數(shù)用于設(shè)定新窗口的功能。因?yàn)樵搮?shù)是可選的,如果沒有指定該參數(shù),新窗口有所有的標(biāo)準(zhǔn)功能。
replace
可選布爾參數(shù),設(shè)置新窗口中的操作歷史的保存方式。
true - 創(chuàng)建新歷史記錄
false - 替換舊的歷史記錄
Returns - 返回值
一個(gè)根據(jù)name參數(shù)對(duì)新創(chuàng)建的或已存在的窗口對(duì)象的引用。
Description - 描述
open()方法可以查找一個(gè)已經(jīng)存在的或者新建的瀏覽器窗口。如果name參數(shù)指定了一個(gè)已經(jīng)存在的劉瀏覽器窗口,則返回對(duì)該窗口的引用。返回的窗口中將顯示URL中指定的文檔,但是features參數(shù)會(huì)被忽略。open()方法是JavaScript中唯一通過名稱獲得瀏覽器窗口引用的途徑。
如果沒有指定name參數(shù),或者不存在name參數(shù)指定的名稱的窗口,open()方法將創(chuàng)建一個(gè)新的瀏覽器窗口。
name參數(shù)用于指定新窗口的名稱,該名稱必須由字母、數(shù)字和下劃線字符組成。它可以被HTML文檔中的<a>標(biāo)記或<form>標(biāo)記指向。
當(dāng)你使用window.open()方法加載一個(gè)新的文檔到一個(gè)已經(jīng)存在了命名的窗口中時(shí),你可以通過replace參數(shù)設(shè)置歷史記錄的保存方式.。如果該參數(shù)是true, 新文檔的歷史記錄將取代舊文檔的歷史記錄。 如果該參數(shù)為false或這沒有指定該參數(shù),新的文件在窗口的瀏覽歷史記錄中將建立自己的條目。該參數(shù)提供了location.replace()相同功能的方式。
不要把"Window.open( ) "和"Document.open( )"混淆;這是兩個(gè)完全不一樣的方法。為了讓代碼更明晰,你可以用"Window.open( )"代替 "open( )"。作為HTML屬性定義事件處理程序時(shí), "open( )" 一般被解釋為"Document.open( )",所以在這種情況下,你必須使用"Window.open( )"。
Window Features - 窗口特性
feature參數(shù)是一個(gè)用逗號(hào)分隔的功能列表。如果該參數(shù)為空或者沒有指定該參數(shù),新的窗口將擁有所有的功能。另一方面, 如果feature參數(shù)只指定了某一項(xiàng)或某幾項(xiàng)功能,那么其他沒有被指定的功能將不會(huì)出現(xiàn)在新的窗口中。該字符串不能包含任何空格或其它空字符串。
列表中的每個(gè)元素的格式:功能[=值]
對(duì)于絕大多數(shù)的功能來說,它們的值一般都是yes或no。對(duì)這些功能,等號(hào)和值都可以省略不寫。 對(duì)于 width和height特性,必須給它們指定一個(gè)以像素為單位的值。
一下是一些普遍支持的功能和它們的含義:
height
設(shè)定窗口顯示區(qū)域的像素寬度
left
瀏覽器窗口距離屏幕左邊的距離
location
指明地址欄在新窗口中是否可見
menubar
指明菜單欄在新窗口中是否可見
resizable
指明新窗口是否可以調(diào)整大小
scrollbars
指明滾動(dòng)欄在新窗口中是否可見
status
指明狀態(tài)欄在新窗口中是否可見
toolbar
指明工具欄在新窗口中是否可見
top
設(shè)定新窗口距屏幕上方的距離
width
設(shè)定窗口顯示區(qū)域的像素寬度
alwaysLowered
指定窗口隱藏在所有窗口之下
alwaysRaised
指定窗口浮在所有窗口之上
dependent
指定打開的窗口為父窗口的一個(gè)子窗口。并隨父窗口的關(guān)閉而關(guān)閉
directions
指定Navigator 2和3的目錄欄是否在新窗口中可見
hotkeys
在沒有菜單欄的新窗口設(shè)置安全退出熱鍵
innerHeight
設(shè)置新窗口中文檔的像素高度
innerWidth
設(shè)置新窗口中文檔的像素寬度
menubar
指明菜單欄在新窗口中是否可見
outerHeight
設(shè)定窗口(包括裝飾邊框)的像素高度
outerWidth
設(shè)定窗口(包括裝飾邊框)的像素寬度
screenX
設(shè)定新窗口離屏幕邊界的像素長(zhǎng)度
screenY
設(shè)定新窗口離屏幕上邊界的像素長(zhǎng)度
titlebar
指明菜單題目欄在新窗口是否可見
z-look
在文檔中包含各個(gè) <pplet>標(biāo)簽的數(shù)組
fullscreen
打開的窗體是否進(jìn)行全屏顯示
四、代碼模擬
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>測(cè)試彈框攔截</title>
<script>
window.open("http://www.cnblogs.com/chenyablog/","測(cè)試彈框","top=nInt,left=nInt,width=nInt,height=nInt,location=yes,menubar=no,resizable=yes,scrollbars=yes,status=no,toolbar=no");
</script>
</head>
<body>
<h1>測(cè)試彈框攔截</h1>
</body>
</html>五、解決方案在
ajax請(qǐng)求之前,先用window.open 打開一個(gè)空白窗口,然后在ajax的響應(yīng)函數(shù)中設(shè)置該窗口的location屬性為新的url。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>測(cè)試彈框攔截</title>
<script>
async displayProjectileFrame (type) {
const title = '測(cè)試彈框攔截'
// 先打開一個(gè)窗口
let newWindow = window.open()
//給新窗口設(shè)置標(biāo)題
newWindow.document.title = title
try {
const base = 'xxxxxxxxxx'
// 這里是模擬ajax,不同使用場(chǎng)景需要有所變化
const openUrl = await this.$axios.$get('/xxx/xxxx', {
params: {
base
}
})
if (openUrl) {
// 重定向
newWindow.location = openUrl
}
} catch (e) {
this.$axiosError(e)
}
}
</script>
</head>
<body>
<h1>測(cè)試彈框攔截</h1>
</body>
</html>六、小結(jié)
上面方法,存在一個(gè)問題時(shí),因?yàn)橄却蜷_了空白窗口,如果ajax請(qǐng)求失敗(網(wǎng)絡(luò)或業(yè)務(wù)邏輯問題)后, 新窗口中就不會(huì)有正常的結(jié)果體現(xiàn),有可能造成用戶疑惑。
一個(gè)解決辦法是,當(dāng)ajax出現(xiàn)問題時(shí),可以考慮給出一個(gè)提示,如 newWindow.document.write("服務(wù)器處理異常");
甚至為了防止ajax響應(yīng)時(shí)間過長(zhǎng),當(dāng)窗口新建后,立即給出提示 newWindow.document.write("服務(wù)器正在處理中,請(qǐng)稍后");
后面如果ajax正常返回,則因?yàn)樵O(shè)置了location值,原來打印的信息會(huì)被新的頁面信息覆蓋。
七、思考
對(duì)于動(dòng)態(tài)打開新窗口,沒有特別完美的方法。具體還需根據(jù)特定的業(yè)務(wù)場(chǎng)景來采取相應(yīng)的做法!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
VSCode中 Eslint 和 Prettier 沖突問題最新解決方法
這篇文章主要介紹了VSCode中 Eslint和Prettier沖突問題,既然使用 eslint規(guī)范,我的理解上當(dāng)然是不能去修改eslint,因?yàn)檫@是共用規(guī)范,修改了就沒有再使用的必要了,所以我是不推薦修改eslint的方式,本文給結(jié)合實(shí)例代碼給大家詳細(xì)講解,需要的朋友可以參考下2023-02-02
微信小程序?qū)崿F(xiàn)圓形進(jìn)度條動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)圓形進(jìn)度條動(dòng)畫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06
js原生實(shí)現(xiàn)FastClick事件的實(shí)例
下面小編就為大家?guī)硪黄猨s原生實(shí)現(xiàn)FastClick事件的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11
javascript中錯(cuò)誤使用var造成undefined
這篇文章主要介紹了javascript中錯(cuò)誤使用var造成undefined的原因,實(shí)例分析了錯(cuò)誤使用var造成undefined的過程,感興趣的小伙伴們可以參考一下2016-03-03
JavaScript判斷數(shù)據(jù)類型的四種方式總結(jié)
JavaScript 作為一門動(dòng)態(tài)語言,其靈活性是把雙刃劍,一方面帶來了開發(fā)的便利性,另一方面也給我們?cè)陬愋团袛鄷r(shí)帶來了挑戰(zhàn),特別是在處理類型轉(zhuǎn)換和隱式轉(zhuǎn)換的時(shí)候,所以本篇文章我們將探討 JavaScript 中的數(shù)據(jù)類型判斷方式及在實(shí)際項(xiàng)目中的應(yīng)用,需要的朋友可以參考下2025-04-04
Ajax實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)實(shí)例代碼
這篇文章介紹了Ajax實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04
處理JavaScript浮點(diǎn)數(shù)精度問題的解決方案
在開發(fā)過程中,特別是涉及到金額計(jì)算或需要精確比較的場(chǎng)景,浮點(diǎn)數(shù)精度問題是一個(gè)常見而重要的挑戰(zhàn),本文將介紹在JavaScript中如何識(shí)別、理解和解決這些問題,并提供一些實(shí)用的技巧和建議,需要的朋友可以參考下2024-06-06

