在項目開發(fā)中, 需要在按鈕點擊后發(fā)出一個ajax請求并在請求完成后, 彈出一個新窗口頁面. 自然想到用window.open實現(xiàn), 但會被瀏覽器攔截
分析
當(dāng)瀏覽器檢測到非用戶操作產(chǎn)生的新彈出窗口,則會對其進(jìn)行阻止。因為瀏覽器認(rèn)為這可能是一個廣告,不是一個用戶希望看到的頁面。
當(dāng)
window.open為用戶觸發(fā)事件內(nèi)部或者加載時,不會被攔截,一旦將彈出代碼移動到ajax或者一段異步代碼內(nèi)部,馬上就出現(xiàn)被攔截的現(xiàn)象。
被攔截示例代碼
例如, 下面這段代碼就會被攔截:
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>{{msg}}</h3>
<button ref='btn' type="button" @click="clickHandler">click</button>
</div>
</template>
<script>
export default {
props: {
msg: {
required: true,
type: String
}
},
data () {
return {
url: 'http://www.baidu.com/',
}
},
mounted () {
setTimeout(() => {
window.open(this.url, '_blank')
}, 100)
}
}
</script>
解決方案
1. 打開新窗口的代碼綁定到click的事件回調(diào)中,就可以避免大部分瀏覽器對窗口彈出的攔截:
如下示例代碼:
button的click事件觸發(fā)的回調(diào)函數(shù)clickHandler內(nèi)打開一個新窗口不會被瀏覽器攔截.
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>{{msg}}</h3>
<button ref='btn' type="button" @click="clickHandler">click</button>
</div>
</template>
<script>
export default {
props: {
msg: {
required: true,
type: String
}
},
data () {
return {
url: 'http://www.baidu.com/',
}
},
mounted () {
},
methods: {
clickHandler () {
window.open(this.url, '_blank')
}
}
}
</script>
2. 通過form表單提交實現(xiàn)(親測, 會被攔截)
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>{{msg}}</h3>
<form action="http://www.baidu.com" ref="form" method="get" target="_blank" style="display: none"></form>
</div>
</template>
<script>
export default {
props: {
msg: {
required: true,
type: String
}
},
data () {
return {
url: 'http://www.baidu.com/',
}
},
mounted () {
setTimeout(() => {
this.$refs.form.submit()
}, 1000)
},
methods: {
}
}
</script>
將上面的代碼改造下, form提交的事件由button按鈕的click事件觸發(fā)的話, 就不會被瀏覽器攔截
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>{{msg}}</h3>
<form action="http://www.baidu.com" ref="form" method="get" target="_blank" style="display: none"></form>
<button type="button" @click='clickHandler'>button</button>
</div>
</template>
<script>
export default {
props: {
msg: {
required: true,
type: String
}
},
data () {
return {
url: 'http://www.baidu.com/',
}
},
mounted () {},
methods: {
clickHandler () {
this.$refs.form.submit()
}
}
}
</script>
3. 先彈出窗口,然后重定向(最優(yōu)方案)
先通過用戶點擊打開頁面(必須是用戶點擊而觸發(fā)的行為),然后再對頁面進(jìn)行重定向
<template>
<div class="about">
<h1>This is an about page</h1>
<h3>{{msg}}</h3>
<button ref="btn" @click="clickHandler">button</button>
</div>
</template>
<script>
export default {
props: {
msg: {
required: true,
type: String
}
},
data () {
return {
url: 'http://www.baidu.com/',
newTab: null
}
},
mounted () {},
methods: {
clickHandler () {
this.newTab = window.open('about:blank')
let $ajax = new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 1000)
})
$ajax.then(() => {
this.newTab.location.href = this.url
setTimeout(() => {
this.newTab = null
}, 1)
})
}
}
}
</script>