JavaScript History API 允许不刷新页面修改 URL、添加或替换历史记录,用于 SPA 路由管理;pushState 添加新记录,replaceState 替换当前记录,popstate 监听导航变化,但无法跨域、读取历史内容或删除记录。

JavaScript 通过 History API 提供对浏览器会话历史的可控访问,不刷新页面即可修改 URL、添加记录或跳转,常用于单页应用(SPA)的路由管理。
使用 pushState 添加新历史记录
调用 history.pushState(state, title, url) 可向历史栈插入一条新记录:
- state:任意可序列化的对象,随 popstate 事件一起传递,可用于保存页面状态
-
title:目前大多数浏览器忽略该参数,传空字符串即可(如
"") - url:相对路径或绝对路径,必须与当前源(origin)同域,否则抛出安全错误
例如:history.pushState({page: "detail", id: 123}, "", "/item/123"); —— 地址栏变为 /item/123,但不触发页面加载。
使用 replaceState 替换当前历史记录
history.replaceState(state, title, url) 不新增记录,而是替换当前条目,适合更新 URL 但不想让用户多按一次“后退”:
立即学习“Java免费学习笔记(深入)”;
- 常用于表单提交后修正 URL,或根据筛选条件动态更新地址栏
- 参数含义与
pushState相同 - 例如:
history.replaceState(null, "", "?sort=price&order=desc");
监听历史变化:popstate 事件
用户点击浏览器前进/后退按钮,或 JS 调用 history.back()、history.forward()、history.go(n) 时,会触发 popstate 事件:
- 需在
window上监听:window.addEventListener("popstate", (e) => { console.log(e.state); }); -
e.state是之前pushState或replaceState传入的状态对象 - 注意:仅由浏览器导航行为触发,
pushState/replaceState不会触发该事件
注意事项与常见限制
History API 不能跨域操作,也不能读取历史栈内容(如获取上一页 URL),出于隐私保护,JS 无法获知用户历史记录长度或具体地址:
-
history.length仅返回当前会话中历史条目数量,不可靠且不包含 iframe 历史 - 不能删除或修改历史中的某一条记录,只能追加或替换当前项
- 服务端仍需正确配置,确保直接访问
/item/123时能返回对应页面(前端路由需服务端 fallback)










