瀏覽器攔截開啟新視窗情況總結

toBeTheLight發表於2018-11-04

在開啟一個新視窗時,由於瀏覽器的安全機制,使用者未始終允許的情況下,可能會觸發到瀏覽器攔截,無法正常直接彈出。

網上有很多給出解決方案的隻言片語,不夠全面,所以針對自己遇到的問題做了詳細的情況分析。總結成文,避免以後混淆。

只分析列舉使用 js 程式碼手動開啟新視窗的方式。

測試程式碼用例在此

幾種開啟新視窗的方式

  1. window.open()
  2. 創造 a 連結,手動觸發 a.click()
  3. 創造 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

使用者點選行為

  1. 按鈕點選後直接開啟

    即在按鈕被點選的回撥中,直接呼叫開啟新視窗的程式碼

    方式 Chrome Firefox Edge IE
    window.open()
    a.click()
    form.submit()
  2. 按鈕點選後延時開啟

    即在按鈕被點選的回撥中,通過 setTimeout 執行開啟新視窗程式碼

    方式 Chrome Firefox Edge IE
    window.open() × ×
    a.click() × ×
    form.submit() × ×
  3. 按鈕點選後在非同步請求回撥中開啟

    即在按鈕被點選的回撥中,傳送請求,並在請求的回撥中執行開啟新視窗程式碼

    方式 Chrome Firefox Edge IE
    window.open() x x x x
    a.click() x x x x
    form.submit() x x x x

使用者鍵盤行為

我們以 input 元素進行測試(其他元素其他鍵盤事件也有相同效果),因為最可能使用的情況為 input 中使用回車開啟新視窗。

  1. input keydown後直接開啟

    方式 Chrome Firefox Edge IE
    window.open() x x
    a.click() x x
    form.submit() x x

    其中 ie9、ie10雖然會彈出攔截彈窗提示,但是能開啟新視窗

  2. 按鈕點選後延時開啟

    方式 Chrome Firefox Edge IE
    window.open() x x x
    a.click() x x x
    form.submit() x x x
  3. 按鈕點選後在非同步請求回撥中開啟

    方式 Chrome Firefox Edge IE
    window.open() x x x x
    a.click() x x x x
    form.submit() x x x x

規則總結

  1. 就參與測試的瀏覽器,三種開啟新視窗的方式對攔截結果沒有影響。
  2. 所有瀏覽器都不允許非使用者操作引起的開啟新視窗。
  3. 所有瀏覽器都不允許在非同步 ajax 請求中開啟新視窗。
  4. Edge 和 IE 不允許在 setTimeout 中開啟新視窗,Chrome、Firefox 允許在使用者操作事件中的 setTimeout 中開啟新視窗。
  5. Firefox 和 IE 不允許在使用者鍵盤操作事件中開啟新視窗

解決方案

  1. 需要在非同步 ajax 請求中開啟新視窗的可以使用請求前開啟新視窗,請求拿到結果後再修改視窗地址的方式。
  2. 需要在鍵盤迴車事件中開啟新視窗的推薦使用 form 表單包裝並新增 button 的方式,回車觸發預設的 submit 事件進行新視窗的開啟。

相關文章