一、前言
最近有客户反馈点击某个功能按钮没效果,听描述以为是调用的接口报错,后远程发现客户用的是苹果电脑,浏览器把页面拦截了
该按钮的点击事件设计为调用一个接口,随后使用window.open来打开接口返回的URL。问题在于,因为这是一个异步操作的结果,浏览器通常会将这类不是直接由用户动作触发的行为视作潜在的不受欢迎的弹窗,并自动将其拦截。浏览器的这种行为是一种安全措施,其目的在于防止用户体验被恼人的广告或恶意行为破坏,这种安全措施是有其合理性的。
二、解决
为了解决这个问题并优化用户体验,我们需要调整代码,确保在用户的直接交互下(如点击按钮)同步调用window.open,让其变成用户行为,而不会被浏览器拦截。
但是要考虑用户打开空白页到页面完成的等待、请求失败的情况
1、抽离一个打开页签的公共方法
/**
* @description: 打开新页签
* @param {fetchWindowURL : Promise} : 获得URL的Promise方法
* @return void
*/
const openNewWindow = (fetchWindowURL) => {
// 打开一个新的空白标签页
const newTab = window.open("about:blank", "_blank");
if (!newTab) {
alert("弹出窗口被拦截, 请允许弹窗");
return;
}
// 显示加载状态
newTab.document.body.innerText = "正在加载,请稍候…";
// 执行异步请求获取URL
fetchWindowURL()
.then((windowURL) => {
// 更新新标签页的地址
newTab.location.href = windowURL;
})
.catch((error) => {
console.error("无法获取窗口URL", error);
newTab.close(); // 获取URL失败,关闭新标签页
});
};
2、vue组件
getExampleURL(){
openNewWindow(
new Promise((resolve, reject) => {
// 模拟API请求
setTimeout(() => {
const res = {
code: 200,
data: "https://juejin.cn/",
message: "操作成功",
};
if (res.code === 200 && res.data) {
resolve(res.data);
} else {
reject(res.message);
}
}, 1000);
})
)
};