hash 和 history 两种模式的区别

1. hash 模式

URL 地址栏中的 # 代表网页中的一个位置,是网页的锚点。

  • # 前面是 URL,后面是 hash 值。
  • hash 发生变化的 URL 会被浏览器记录下来,这样就可以前进 / 后退。
  • 浏览器向服务端发送请求时,只会把 # 前的链接发送给服务端,并且页面可以刷新,不会返回 404 之类的错误页面。

2. history 模式

History API 可以分为两大部分:切换 和 修改。

切换历史状态

包括 back、forward、go 三个方法:

history.back()     // 后退
history.forward()  // 前进
history.go(-1)     // 后退一步,等价于 history.back()
history.go(1)      // 前进一步,等价于 history.forward()

修改历史状态

包括 pushState 和 replaceState 两个方法。这两个方法接收三个参数:stateObj、title、url:

history.pushState(stateObj, title, url)
history.replaceState(stateObj, title, url)

通过 pushState 把页面的状态保存在 state 对象中。当页面的 url 再变回这个 url 时,可以通过 event.state 取到这个 state 对象,从而对页面状态进行还原。这里的页面状态可以是页面字体颜色、滚动条位置、阅读进度、组件开关等。

window.addEventListener('popstate', event => {
  console.log('location: ' + document.location)
  console.log('state: ' + JSON.stringify(event.state))
})

总结

  • hash 模式:URL 永远带 #,不会发送到服务端,不需要服务端配合,刷新、SEO 友好性差。
  • history 模式:URL 干净美观(没有 #),需要服务端把所有未匹配的路径都 fallback 到 index.html,否则刷新会出现 404。

History 模式跟 hash 最大的区别就是没有 #,并且请求服务器的时候发送一整条 url。如果服务器中没有相应的响应或者资源,会分分钟刷出一个 404 来。

来源整理自:vue3js.cn 面试官系列