登录成功要跳首页,很多人写 location.href = '/home',也有人写 location.replace('/home')。两者看起来都是跳转,实际差别在浏览器的返回按钮上,用错场景会让用户回不去。

三个方式的核心区别

  • location.href = url:产生一条新的历史记录,用户点返回会回到原来的页面。
  • location.assign(url):和 href 效果完全一样,也是新增历史记录。
  • location.replace(url):用新地址替换当前历史记录,点返回会直接跳过被替换的那一页。

第三点就是它的全部价值。当前页面不再留在历史栈里。

什么时候该用 replace

典型场景是「中间页跳转」:

// 登录成功后
location.replace('/dashboard');

// 权限校验失败
if (!hasPermission) location.replace('/no-auth');

登录页被替换之后,用户点返回不会再回到登录页,避免出现「返回后还显示已登录表单」的混乱。旧版浏览器里,从 HTTPS 跳到 HTTP 时也会提示混合内容,replace 能规避一些历史记录相关问题。

分页、tab 切换这类需要用户来回走的地方,绝对不能用 replace,否则一路返回就直接退出站点了。

它不刷新,也不保证立刻跳

location.replace 只是发起导航,不是同步执行。写在它后面的代码,部分浏览器会继续执行完,但页面已经开始卸载,DOM 操作随时可能失效。正确的做法是跳转前把要做的事做完,日志、埋点、缓存,别指望跳转后再执行。

几个常见问题

  • 返回键失效:跳转后点返回回到了更早的页面,说明被替换的是当前页,这是预期行为,不是 bug。
  • 只在部分浏览器生效:某些 WebView 或小程序环境对 history 的处理不一致,要做降级处理。
  • 单页应用里不要用:使用 history.pushState 的 SPA,应该用路由的 replace 方法,直接调 location.replace 会整页刷新,状态全丢。
  • 带参数跳转:参数拼在 URL 上要 encodeURIComponent,hash 路由还要注意别被截断。

记住一句:需要留下足迹用 href 或 assign,不想让用户回头找回这一页就用 replace。