以前的項目,有個功能是下載文件,這裏只要在瀏覽器輸入 url 就會下載那個文件了。當時我只是簡單得使用
window.open
,可是卻會被瀏覽器進行攔截,要手動開啓才行,而後就搜索研究其餘方法,就看到各類各樣的,經過 js 打開新窗口的方法了,這裏就總結一下html
這裏就先說解決下載功能的方法,經過同事的提醒,改用 iframe 進行處理,直接對 iframe 的 src 進行賦值,就會自動進行下載文件了,不過,若是後端在 response header 設置了某個頭部,就會報錯了:x-frame-options: DENY前端
x-frame-options,是否容許 object 和 iframe 展現,有三個參數:後端
MDN的解釋api
個人後端同事在要下載的幾個接口中,把 x-frame-options
設置成 SAMEOPIGIN
後,前端就能夠在無任何反作用的狀況下,經過 js 進行下載文件了瀏覽器
export: (url) => { // 移除舊的節點 const oldNode = document.querySelector('#g-exportOrder-iframe') if (oldNode) { document.body.removeChild(document.querySelector('#g-exportOrder-iframe')) } // 生成新節點,進行下載 const iframe = document.createElement('iframe') iframe.style.display = "none" iframe.id = 'g-exportOrder-iframe' iframe.src = url document.body.appendChild(iframe) }
只要調用傳個 url ,就會自動下載一個文件了app
若是咱們是點擊一個目標,而後同步執行打開窗口操做,用 window.open
是能夠的,可是咱們把 window.open
放在異步操做裏就有問題了異步
div.addEventListener('click', open, false) function open() { setTimeout(() => { window.open('/api/admin/adslot/all') }, 1100) }
我在谷歌、火狐和歐朋,這樣就會被攔截,然而用 ie9 卻不會被攔截,我給10秒,ie 最後仍是會彈出來url
從你用點擊事件,到 window.open
,只要異步操做超過某個時間,瀏覽器就會攔截這個彈窗的操做code
若是不添加用戶的事件去觸發 window.open
(好比點擊事件,鼠標移入移出等),而是在代碼直接運行 window.open
的話,那樣瀏覽器也會攔截orm
window.onload = function() { windon.open() }
總得來說,若是沒有用用戶操做的事件去觸發 window.open
就會被攔截,而把 window.open
放在異步操做,且超過必定的事件,也會被攔截
這裏先想到了解決異步也會被攔截的方法
var test = window.open() setTimeout(function() { test.location = 'http://www.xxx.com' }, 2000)
在異步操做前,先打開窗口,而後再在你要操做的位置,更改這個窗口的 location
,不過這個缺陷有點大,要等異步操做完成了,新的窗口才會從空白變到指定頁面,並且這種解決不了,沒有人爲事件觸發 window.open
致使被攔截的問題
這是最多見打開一個新標籤頁面的方法
<a class='test' href='http://www.xxx.com' target='_blank'></a>
而後,我點擊另一個 div ,再打開新窗口
function open() { setTimeout(function() { document.querySelector('.test').click() }, 2000) }
上面的異步操做,仍是不行,就算是從新生成一個 a 標籤,再用 click()
觸發也是不行
<form class='test' target='_blank' @click='open' method='GET' action='http://www.xxx.com'>click me</form> function open2() { setTimeout(() => { document.querySelector('.test').submit() }, 2000) }
和 a 標籤同樣
若是要下載文件的話,使用 iframe
若是要打開新窗口,並且沒有用戶操做的前提下打開,是不能顯示的,只能提示讓用戶關閉那個攔截吧
有用戶操做,且是異步的狀況下,就使用 window.open
,而後定義 location
這樣就行了