JavaScript 通过 history.pushState() 和 replaceState() 操作同源历史栈,支持无刷新更新 URL 和状态;popstate 事件监听导航变化;back/forward/go 仅限已存在历史项跳转,且需用户手势触发。

JavaScript 可以读取、跳转甚至修改当前标签页的浏览历史,但受同源策略和隐私限制,无法获取其他网站的历史记录,也不能直接读取完整 URL 列表。它的核心能力集中在当前页面所在域名的历史栈操作上。
用 history.pushState() 添加新历史条目
这个方法不会刷新页面,但会在浏览器历史中新增一条记录,并可更新 URL 和状态对象:
- 语法:
history.pushState(state, title, url) -
state是一个可序列化的对象,会在 popstate 事件中传回 -
title当前多数浏览器忽略,可传空字符串 -
url必须与当前页面同源(协议+域名+端口),可以是相对路径 - 例如:点击“加载更多”后执行
history.pushState({page: 2}, '', '?page=2'),地址栏变为?page=2,用户点返回会回到上一页
用 history.replaceState() 替换当前历史条目
和 pushState 类似,但不新增记录,而是覆盖当前这一项。常用于修正 URL 或避免用户重复提交:
- 适合表单提交后重写 URL,比如从
/submit改成/success,防止刷新重复提交 - 调用后历史长度不变,返回按钮仍指向上一条,不是当前这条
监听历史变化:popstate 事件
当用户点击前进/后退按钮,或 JS 调用 history.back() 等时触发:
立即学习“Java免费学习笔记(深入)”;
- 需通过
window.addEventListener('popstate', handler)绑定 - 事件对象的
state属性就是 pushState/replaceState 传入的状态对象 - 注意:首次加载页面不会触发 popstate,即使 URL 带有 state
- 典型用途:根据 URL 参数动态渲染内容,实现无刷新路由
基础导航控制(有限且谨慎使用)
JS 可以模拟浏览器按钮行为,但受限明显:
-
history.back()、history.forward()、history.go(n)—— 只能跳转已存在的历史项 - 不能跳转到跨域页面,也不能跳转到用户未访问过的地址
- 部分浏览器在非用户手势(如自动 setTimeout)中调用会静默失败
- 实际项目中更推荐用 pushState + popstate 构建可控的导航逻辑
不复杂但容易忽略:所有 history API 操作都要求页面已完成加载,且必须在同源上下文中运行。现代前端框架(React Router、Vue Router)底层正是基于这些机制实现路由功能。










