Safari中window.location.href跳转失效求助(其他浏览器正常)
Safari中axios异步回调后window.location.href跳转失效的解决方案
我之前也碰到过一模一样的问题!这其实是Safari的安全机制在搞鬼,核心原因是:
Safari对用户交互触发的页面跳转有更严格的限制——它会阻止非用户直接触发的异步操作修改
window.location。你的window.location.href = url是在axios的异步回调(.then())里执行的,虽然这个回调起源于用户点击,但Safari会把它判定为「非直接用户交互行为」,所以直接拦截了跳转;而Chrome等浏览器的安全限制没这么严苛,因此可以正常工作。
下面给你几个可行的解决方案:
方案1:创建标签模拟用户点击跳转
这是最可靠的解决方式,因为标签的点击行为会被Safari认定为用户主动操作:
修改你的代码如下:
getSites = async (e, param) => { try { const res = await axios.get(`${Config.siteInfo}`); if (res.status === 200 && res.data?.data) { if (param === 'baidu') { const url = res.data.data[0].site; // 创建临时a标签 const tempLink = document.createElement('a'); tempLink.href = url; tempLink.target = '_self'; // 当前窗口打开用_self,新窗口用_blank // 必须添加到DOM中才能触发点击 document.body.appendChild(tempLink); tempLink.click(); // 用完移除临时标签 document.body.removeChild(tempLink); } } } catch (error) { console.log('getSites error:', error); } }
方案2:提前标记用户交互状态(备选)
你也可以在用户点击的同步阶段标记一个状态,再在异步回调里基于这个状态执行跳转,不过这个方法的稳定性不如方案1:
// 在组件内添加一个状态变量 hasUserTriggered = false; getSites = async (e, param) => { // 同步阶段标记用户已触发交互 this.hasUserTriggered = true; try { const res = await axios.get(`${Config.siteInfo}`); if (res.status === 200 && res.data?.data && this.hasUserTriggered) { if (param === 'baidu') { const url = res.data.data[0].site; window.location.href = url; } } } catch (error) { console.log('getSites error:', error); } finally { // 完成后重置状态 this.hasUserTriggered = false; } }
额外排查点
最后再确认下你的url是不是完整的带协议地址(比如https://www.baidu.com),如果是相对路径或缺少协议,Safari也可能出现解析异常——虽然你说url值正确,但还是可以快速排查一下~
内容的提问来源于stack exchange,提问作者BigheadSoldier
相关产品推荐
相关产品推荐

