在打開一個新窗口時,由於瀏覽器的安全機制,用戶未始終允許的情況下,可能會觸發到瀏覽器攔截,無法正常直接彈出。
網上有很多給出解決方案的隻言片語,不夠全面,所以針對自己遇到的問題做了詳細的情況分析。總結成文,避免以後混淆。
只分析使用 js 代碼手動打開新窗口的方式。
幾種打開新窗口的方式
window.open()
- 創造 a 鏈接,手動觸發
a.click()
- 創造 form 表單,手動觸發
form.submit()
(創造 form 表單,添加 button 子元素,手動觸發button.click()
情況相同,不做區分)
調用情形分組結果
使用 Chrome(70)、Firefox(63)、Edge、IE(9-11) 作爲測試瀏覽器,對以下列舉的打開新窗口的情形做測試。
x 表示被攔截,√ 表示新窗口正確打開
直接打開
即頁面加載後直接調用打開新窗口代碼
方式 | Chrome | Firefox | Edge | IE |
---|---|---|---|---|
window.open() | x | x | x | x |
a.click() | x | x | x | x |
form.submit() | x | x | x | x |
用戶點擊行爲
-
按鈕點擊後直接打開
即在按鈕被點擊的回調中,直接調用打開新窗口的代碼
方式 Chrome Firefox Edge IE window.open() √ √ √ √ a.click() √ √ √ √ form.submit() √ √ √ √ -
按鈕點擊後延時打開
即在按鈕被點擊的回調中,通過 setTimeout 執行打開新窗口代碼
方式 Chrome Firefox Edge IE window.open() √ √ × × a.click() √ √ × × form.submit() √ √ × × -
按鈕點擊後在異步請求回調中打開
即在按鈕被點擊的回調中,發送請求,並在請求的回調中執行打開新窗口代碼
方式 Chrome Firefox Edge IE window.open() x x x x a.click() x x x x form.submit() x x x x
用戶鍵盤行爲
我們以 input 元素進行測試(其他元素其他鍵盤事件也有相同效果),因爲最可能使用的情況爲 input 中使用回車打開新窗口。
-
input keydown後直接打開
方式 Chrome Firefox Edge IE window.open() √ x √ x a.click() √ x √ x form.submit() √ x √ x 其中 ie9、ie10雖然會彈出攔截彈窗提示,但是能打開新窗口
-
按鈕點擊後延時打開
方式 Chrome Firefox Edge IE window.open() √ x x x a.click() √ x x x form.submit() √ x x x -
按鈕點擊後在異步請求回調中打開
方式 Chrome Firefox Edge IE window.open() x x x x a.click() x x x x form.submit() x x x x
規則總結
- 就參與測試的瀏覽器,三種打開新窗口的方式對攔截結果沒有影響。
- 所有瀏覽器都不允許非用戶操作引起的打開新窗口。
- 所有瀏覽器都不允許在異步 ajax 請求中打開新窗口。
- Edge 和 IE 不允許在 setTimeout 中打開新窗口,Chrome、Firefox 允許在用戶操作事件中的 setTimeout 中打開新窗口。
- Firefox 和 IE 不允許在用戶鍵盤操作事件中打開新窗口
解決方案
- 需要在異步 ajax 請求中打開新窗口的可以使用請求前打開新窗口,請求拿到結果後再修改窗口地址的方式。
- 需要在鍵盤迴車事件中打開新窗口的推薦使用 form 表單包裝並添加 button 的方式,回車觸發默認的 submit 事件進行新窗口的打開。