history.pushState 改变 URL 不刷新页面,仅更新历史栈和地址栏,不触发 popstate 事件或路由匹配,需手动处理 DOM 更新;replaceState 替换当前记录,不增加 history.length;两者均要求同源 URL,state 限 640KB 且必须可序列化。

history.pushState 会改变 URL 但不触发页面刷新
这是它和 location.href 最本质的区别:浏览器地址栏变了,document 不重载,JS 上下文保持完整。适合单页应用(SPA)做无跳转导航,比如 React Router、Vue Router 底层都靠它驱动。
常见错误是以为调用后会自动触发路由匹配逻辑——不会。pushState 只改历史栈和 URL,后续的 DOM 更新、组件切换得你自己写,或者交给路由库处理。
-
history.pushState(state, title, url)三个参数里,title当前所有主流浏览器都忽略,传空字符串就行 -
url必须同源,跨域会直接抛SecurityError -
state是任意可序列化的 JS 值(对象、字符串、数字),会被存进历史记录,后面通过popstate事件取回 - 如果传入相对路径(如
"./search?q=js"),浏览器会自动解析为当前 origin 下的绝对路径
监听 history 变化要用 popstate,不是 hashchange
popstate 是唯一能捕获 pushState 和 replaceState 触发的前进/后退动作的事件。注意它只在用户点击浏览器「后退」「前进」按钮,或调用 history.back() 等 API 时触发,**不会**在 pushState 调用时立即触发。
容易踩的坑是把 popstate 绑定在 window 上却忘了加 useCapture: false(默认就是 false,一般不用显式写),更关键的是:这个事件的 event.state 就是你之前传给 pushState 的那个 state 对象,别指望它包含 URL 或其他元信息。
立即学习“前端免费学习笔记(深入)”;
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 必须用
window.addEventListener('popstate', handler),不能用onpopstate = handler(后者无法可靠移除) - 首次页面加载时,
popstate**不会触发**,哪怕 URL 带有 state —— 这是规范行为,需手动检查history.state初始化状态 - 如果用
replaceState替换当前记录,再点后退,会回到上一条记录,而不是“撤销 replace”
state 对象大小限制约 640KB,超限静默失败
Chrome、Firefox 都对单条 history 记录的 state 序列化后大小有限制(实测约 640KB),超过后 pushState 不报错,但 history.state 会变成 null,且后续 popstate 事件里也拿不到数据。这问题很难调试,因为控制台不提示。
典型场景是误把整个 React 组件实例、大型数组或 base64 图片字符串塞进 state。正确做法是只存轻量 ID 或关键标识符,真实数据走内存缓存或重新拉取。
- 用
JSON.stringify(state).length提前判断大小,超过 500KB 就该警告或裁剪 - 避免在
state中存函数、DOM 节点、Date 实例等无法序列化的值(会丢失或变null) - 如果需要持久化复杂状态,考虑配合
sessionStorage,只在state里存一个 key
replaceState 和 pushState 的核心区别在历史栈长度
replaceState 不新增历史记录,而是替换当前这一条;pushState 则追加一条新记录。这意味着:连续调用 5 次 replaceState,后退按钮最多只能退一步;而 5 次 pushState 后,要按 5 次后退才能回到原始页面。
实际开发中,replaceState 更适合修正当前 URL(比如表单提交后清理 query 参数),避免用户误点后退回到未提交状态;pushState 才是构建导航历史的主力。
- 两者参数完全一致:
replaceState(state, title, url) - 调用
replaceState后,history.length不变;pushState会让它 +1 - 服务端无需为
pushState生成新 HTML —— 但要注意:用户直接访问该 URL 时,仍需服务端返回同一份 SPA 入口 HTML,否则 404
pushState URL,用户刷新就 404,这是最常被忽略的一环。


















