History 对象
浏览器中 `history` 对象的前进后退、会话历史和状态管理能力说明。
#tech / dev / frontend
#type / concept
#status / growing
#resource / javascript
#platform / browser
[!info] related notes
- 所属 MOC: javascript-in-browser-moc
- 上位主题: javascript-in-browser
- 上位主题: javascript-bom
- 前置概念: window-object, location-object
- 关系笔记: 浏览器导航与前端路由
History 对象
history 是浏览器会话历史的脚本接口。它让当前页面可以控制前进、后退,以及在不整页刷新的情况下写入历史状态。
一句话定义
history 用来操作当前标签页会话历史,而不是读取用户全部浏览历史。
它背后的底层对象
浏览器会为当前 tab 维护一条会话历史。history 对象只是脚本侧的入口,用来:
- 在历史栈里前进和后退
- 读取当前条目的
state - 在不整页刷新的前提下写入新的历史条目
如果把 URL 变化、浏览器导航和前端路由放在一起看,history 就是最关键的底层骨架之一。
它解决什么问题
当你需要:
- 返回上一页
- 前进到下一页
- 在 SPA 中更新 URL 但不整页刷新
- 给历史记录附带状态对象
通常会用到 history。
常见属性
length
表示当前会话历史条目数量。
console.log(history.length)
它只能告诉你条目数量,不能把每一条具体历史内容暴露给脚本。
state
返回当前历史条目上关联的状态对象。
console.log(history.state)
这个值常和 pushState() / replaceState() 配合。
常见方法
back()
回到上一页。
history.back()
forward()
前进到下一页。
history.forward()
go()
按相对步数移动。
history.go(-1) // 后退
history.go(1) // 前进
history.go(0) // 刷新当前页
pushState()
向历史栈新增一条记录,同时允许改 URL 而不整页刷新。
history.pushState({ tab: 'profile' }, '', '/account/profile')
这也是很多 SPA 路由实现的基础。
replaceState()
替换当前历史条目,不新增记录。
history.replaceState({ tab: 'profile' }, '', '/account/profile')
适合修正当前地址或状态,但不希望用户“后退一步又回到旧 URL”。
popstate 事件
用户通过浏览器前进后退按钮切换历史记录时,页面通常会收到 popstate 事件。
window.addEventListener('popstate', (event) => {
console.log(event.state)
})
在 SPA 里,这通常意味着:
- URL 变了
- 需要同步切换页面状态
和 location 的关系
location更偏当前地址与直接跳转history更偏历史栈和状态迁移
例如:
location.assign('/a'):直接导航到/ahistory.pushState({}, '', '/a'):把 URL 改成/a,但不整页刷新
最小示例
history.pushState({ page: 2 }, '', '/list?page=2')
window.addEventListener('popstate', (event) => {
console.log('restore state:', event.state)
})
运行时边界
history不能让脚本读取用户完整访问记录pushState()改地址不代表真正访问了服务端新页面- URL 虽然变了,但页面内容是否更新,要由你的前端逻辑负责
常见误区
- 以为
history能查看完整历史详情,实际上浏览器不会暴露这些隐私数据 - 以为
pushState()会自动刷新页面,它本身不会 - 以为
replaceState()和pushState()只差名字,实际上一个替换当前条目,一个新增历史条目
最短记忆方式
history 负责操作会话历史栈;它最重要的价值,在于“前进后退”和“SPA 状态化 URL”。