在 JavaScript 中,我们可以使用 history 对象来操作当前窗口的浏览历史(如前进、后退)。
提示: history 对象本质上是 “window 对象” 的属性。因此在使用时,可以省略 “window.” 前缀。
JavaScript history 对象的属性
在 JavaScript 中,history 对象主要提供了 2 个属性:
length:获取访问历史记录中的数量。state:获取当前历史状态。
示例 1:使用 history.length
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
console.log("当前会话历史记录的数量:", history.length);
</script>
</body>
</html>
运行结果如下。
当前会话历史记录的数量:7JavaScript history 对象的方法
在 JavaScript 中,history 对象主要提供了 5 种方法,如下表所示。
| 方法 | 说明 |
|---|---|
| back() | 加载前一个 URL |
| forward() | 加载后一个 URL |
| go(n) | 加载历史列表中指定位置的 URL |
| pushState() | 在会话历史记录中,添加一个新的条目 |
| replaceState() | 在会话历史记录中,用新状态替换掉当前的条目 |
提示: 由于客观存在的技术原因,使用绿叶网的 HTML 在线编译器运行 history 对象方法会有问题。对于本节后面的例子,建议小伙伴们在本地自行测试。
示例 2:history.back() 和 history.forward()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button id="back">后退</button>
<button id="forward">前进</button>
<script>
// 后退
const oBack = document.getElementById("back");
oBack.addEventListener("click", function() {
history.back();
});
// 前进
const oForward = document.getElementById("forward");
oForward.addEventListener("click", function() {
history.forward();
});
</script>
</body>
</html>
页面效果如下图所示。

分析:
history.back() 方法用于加载历史列表中的前一个 URL,相当于用户点击了浏览器的 “后退” 按钮。而 history.forward() 方法用于加载历史列表中的下一个 URL,相当于用户点击了浏览器的 “前进” 按钮。
比如绿叶网的 404 页面,就使用了 history.back() 方法来实现 【返回上页】的功能,如下图所示。

示例 3:history.go()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button id="back">后退 2 步</button>
<button id="forward">前进 2 步</button>
<script>
// 后退
const oBack = document.getElementById("back");
oBack.addEventListener("click", function() {
history.go(-2);
});
// 前进
const oForward = document.getElementById("forward");
oForward.addEventListener("click", function() {
history.forward(2);
});
</script>
</body>
</html>
页面效果如下图所示。

分析:
history.go(n) 方法用于加载历史列表中的指定步数的 URL。n 的取值可以是以下几种情况:
- 当取值为 “0” 时,表示重新加载当前页面,与 location.reload() 一样。关于 location.reload() 的使用,另请参阅:JavaScript location 对象。
- 当取值为 “正数(1、2、3等)” 时,表示向前(forward())跳转指定的步数。
- 当取值为 “负数(-1、-2、-3等)” 时,表示向后(back())跳转指定的步数。
管理 SPA 状态:pushState() 和 replaceState()
我们都知道,Vue、React 等都是单页应用(SPA)。而在这些单页应用中,我们经常需要在不刷新页面的情况下更改 URL,以实现书签功能。
其中,history 对象的 pushState() 和 replaceState() 这两个方法,就是为此目的而设计的。
1. history.pushState()
在 JavaScript 中,我们可以使用 history.pushState() 方法来向会话历史记录中添加一个新的条目。history.pushState() 会更改浏览器的 URL,但不触发页面跳转。
语法:
history.pushState(state, title, url)说明:
history.pushState() 方法接收以下 3 个参数。
state(必选):与新历史记录条目关联的状态对象,我们可以使用 history.state 来访问状态对象。title(必选):页面的新标题(大多数浏览器目前忽略此参数)。url(可选):新的历史记录条目 URL。
示例 4:history.pushState() 基本用法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
const newState = { "user_id": 1001, "view": "profile" };
const newUrl = "/users/1001/profile";
history.pushState(newState, "用户资料页", newUrl);
</script>
</body>
</html>分析:
上面代码运行之后,浏览器地址栏会变为 “/users/1001/profile”。其中,history.pushState(newState, "用户资料页", newUrl) 可以在不刷新页面的情况下,将 URL 变为 “/users/1001/profile”,并保存状态(newState)。
提示: 当用户点击浏览器的 “前进/后退” 按钮时,会触发 popstate 事件,SPA 框架(如Vue、React 等)就是靠监听这个事件来切换页面的。
2. history.replaceState()
在 JavaScript 中,history.replaceState() 方法不创建新的历史记录条目,而是用新状态替换掉当前的条目。它经常用于避免在用户执行某些操作时创建不必要的历史记录。
语法:
history.replaceState(state, title, url)说明:
history.replaceState() 与 history.pushState() 语法一样,也接收以下 3 个参数。
state(必选):与新历史记录条目关联的状态对象,我们可以使用 history.state 来访问状态对象。title(必选):页面的新标题(大多数浏览器目前忽略此参数)。url(可选):新的历史记录条目 URL。
示例 5:history.replaceState() 基本用法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
const updatedState = { "view": "settings" };
const updatedUrl = "/user/settings";
history.replaceState(updatedState, "用户设置页", updatedUrl);
</script>
</body>
</html>分析:
history.replaceState() 方法会替换当前历史记录条目,而不是添加新的。
