问题描述
本人的某个项目场景中,需要进行订单支付,点击支付按钮后会调用某个接口(使用axios),接口返回成功后,会打开支付页面,这时,在某些浏览器里(如:火狐浏览器)会提示是否阻止弹出窗口,导致窗口无法自动弹出,需要用户进行设置才能打开支付页面,如图:
原因分析:
查阅网上资料得知,当浏览器检测到非用户操作产生的新弹出窗口,就会对其进行阻止。
经本人测试,下面两种情况弹窗会被拦截:
- 页面初始化,异步延迟执行跳转
<body>
<h1>订单页</h1>
</body>
<script>
setTimeout(() => {
window.open('/pay.html')
}, 500);
</script>
- 接口请求返回中执行跳转
<body>
<h1>订单页</h1>
<button>跳转支付</button>
</body>
<script>
const btn = document.querySelector('button')
btn.addEventListener('click', function () {
// 调用接口
axios.get('https://api.github.com/zen').then(res => {
window.open('/pay.html')
})
})
</script>
解决方案:
- 方案1
将异步延迟跳转放到用户操作的事件中,如点击:
<body>
<h1>订单页</h1>
<button>跳转支付</button>
</body>
<script>
const btn = document.querySelector('button')
btn.onclick = function() {
setTimeout(() => {
window.open('/pay.html')
}, 500);
}
</script>
- 方案2
创建a链接模拟跳转
<body>
<h1>订单页</h1>
<button>跳转支付</button>
</body>
<script>
const btn = document.querySelector('button')
btn.addEventListener('click', function () {
const a = document.createElement('a');
const id = 'newpage'
const url = 'pay.html'
a.setAttribute('href', url);
a.setAttribute('target', '_blank');
a.setAttribute('id', id);
// 防止反复添加
if(!document.getElementById(id)) {
document.body.appendChild(a);
}
a.click();
})
</script>
- 方案3(推荐👍)
根据文档说明,我们可以先创建一个未载入的空白窗口,然后等待接口返回成功后再更改其url,代码如下:
<body>
<h1>订单页</h1>
<button>跳转支付</button>
</body>
<script>
const btn = document.querySelector('button')
btn.addEventListener('click', function () {
const newPage = window.open(); // 打开一个不被拦截的空白窗口
// 调用接口
axios.get('https://api.github.com/zen').then(res => {
newPage.location.href = '/pay.html' // 修改空白窗口的url
})
})
</script>