You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

安卓端Chrome93点击浏览器返回键未触发popstate事件问题求助

问题根因
  • 安卓Chrome 93及以上版本对无用户交互触发的pushState操作做了策略限制,页面加载初期同步执行的pushState如果传入空state、且未关联任何用户行为,会被浏览器判定为非用户主动产生的无效历史记录,返回时会直接跳过该条记录,导致popstate事件完全不触发。
  • Vue 2单页应用如果使用了vue-router,路由自身的历史栈操作和手动调用的pushState存在时序冲突,也会导致手动插入的历史记录失效。
修复方案

方案1:调整原生popstate监听逻辑

调整pushState的参数和执行时机,同时补充历史记录重入逻辑,兼容安卓Chrome的策略限制:

mounted() {
  // 等待Vue异步更新队列清空后执行,避免和路由的历史操作冲突
  this.$nextTick(() => {
    // 避免重复插入相同的自定义历史记录
    if (history.state?.isCustomBackGuard) return
    // 传入非空的state标识,避免被Chrome判定为无效历史记录
    history.pushState({ isCustomBackGuard: true }, null, location.href)
  })

  const handlePopstate = () => {
    alert('触发返回拦截')
    // 此处执行你的自定义操作
    
    // 若需要继续拦截下一次返回,重新插入自定义历史记录即可
    history.pushState({ isCustomBackGuard: true }, null, location.href)

    // 若自定义操作完成后需要正常返回上一页,取消注释下面的代码
    // history.back()
  }

  window.addEventListener('popstate', handlePopstate)

  // 页面销毁前移除事件监听,避免内存泄漏
  this.$once('hook:beforeDestroy', () => {
    window.removeEventListener('popstate', handlePopstate)
  })
}

方案2:使用Vue路由守卫(更推荐)

如果你的项目使用了vue-router,优先使用内置的路由守卫实现返回拦截,兼容性和逻辑一致性更好,无需手动操作历史栈:

export default {
  // ...其他组件选项
  beforeRouteLeave(to, from, next) {
    // 此处执行你的自定义操作
    alert('触发返回拦截')
    
    const allowLeave = false // 替换为你的自定义判断逻辑
    if (allowLeave) {
      next() // 允许离开当前页,返回上一级
    } else {
      next(false) // 阻止离开,停留在当前页
    }
  }
}
补充注意事项

如果页面的返回拦截需要在用户完成特定操作后才激活,建议将pushState逻辑放到用户首次触摸、点击页面的事件回调中执行,和用户行为关联后,安卓Chrome的兼容表现会更稳定。

内容的提问来源于stack exchange,提问作者Cuckoos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 02:24:05