JavaScript History API通过pushState、replaceState和popstate实现SPA路由控制:pushState添加历史记录并更新URL,replaceState替换当前记录,popstate监听前进后退事件以响应状态变化。
JavaScript 的 History API 允许你在不刷新页面的前提下,操作浏览器的会话历史(session history),实现单页应用(SPA)中的路由跳转、前进后退控制和 URL 状态管理。核心是 window.history 对象,它不是只读的,可以安全地增删改当前会话的历史记录。
向历史栈中**追加一条新记录**,改变 URL(可选),但不触发页面刷新或重新加载。
history.pushState(state, title, url)
state:一个可被序列化的对象,随该历史项一起保存,后续通过 popstate 事件可读取(例如:{page: 'detail', id: 123})title:目前大多数浏览器忽略该参数,传空字符串 '' 即可
url:新的相对路径(如 '/post/456')或绝对路径;必须同源,否则报错示例:history.pushState({type: 'article', id: 789}, '', '/article/789'); —— 地址栏变为 /article/789,历史栈多了一条记录。
用新状态**覆盖当前历史项**,URL 改变但不新增历史条目,用户点击「后退」不会回到上一个状态。
pushState 完全一致:history.replaceState(state, title, url)
示例:history.replaceState({sort: 'date'}, '', '?sort=date&limit=20'); —— 当前地址栏更新,但后退键仍指向更早的页面。
当用户点击浏览器「前进」「后退」按钮,或调用 history.back()/history.forward() 时触发,**仅在历史记录切换且 state 非 null 时触发**。
window.addEventListener('popstate', (e) => { console.log(e.state); });
e.state 是 push/replace 时传入的 state 对象(可能为 null)pushState 或 replaceState 不会触发 popstate这是实现 SPA 路由响应的核心机制——根据 e.state 或当前 location.pathname 渲染对应内容。
history.length:当前会话历史总条数(包含当前页),只读history.state:当前历史项的 state 值(即最近一次 push/replace 设置的,或初始页面的 null)history.back() / history.forward() / history.go(n):模拟用户导航行为(go(-1) 等价于 back())⚠️ 注意:所有 History API 操作都受同源策略限制;跨域 URL 会抛出安全错误。
基本上就这些。掌握 pushState、replaceState 和 popstate 就能构建完整的前端路由逻辑,无需依赖服务端跳转。实际使用中建议封装统一的路由函数,并配合 location 解析做兜底,避免状态丢失。