history.back() 不适用于 HTML5 历史记录 API,如 Chrome 中预期的那样

history.back() doesn't work with HTML5 history API as expected in Chrome

history.back() 函数应该让我在使用 HTML5 历史 API 创建的历史中后退一步。以下代码在 Firefox 中按预期工作,但在 Chrome:

中不工作
<html>
    <script type="text/javascript">
        history.replaceState({path: '/home'}, '', '?page=home');
        history.pushState({path: '/second'}, '', '?page=second');
        console.log(history.state.path); // says "/second"
        history.back();
        console.log(history.state.path); // says "/second" but should say "/home"
    </script>
</html>

在Chrome中,它两次打印/second,而返回后它应该打印/home。我错过了什么吗?

在 Chrome 中,history.back / history.forward / history.gohistory.state 不同步。我encountered this issue a while back while working on PDF.js, and reported it at Chromium's issue tracker: https://crbug.com/510026。不过什么也没有出来。

解决方法是使用 popstate event 检测导航何时结束:

history.replaceState({path: '/home'}, '', '?page=home');
history.pushState({path: '/second'}, '', '?page=second');
console.log(history.state.path); // says "/second"

addEventListener('popstate', function(event) {
  console.log(history.state.path); // says "/home"
  // You can also use console.log(event.state);
}, {once: true});
history.back(); // Will asynchronously change history.state

注意:addEventListeneronce 参数仅从 Chrome 55 开始支持 - 在此之前,如果您想要听 运行 一次,像这样:

addEventListener('popstate', function listener(event) {
  removeEventListener('popstate', listener);
  console.log(history.state.path); // says "/home"
  // You can also use console.log(event.state);
});