前端路由的实现有两种方式:hash 和 history。
hash
- 此时浏览器显示的 URL 为
https://aadonkeyz.com/posts/eb815672/。 - 执行
location.hash = '#hash'后,生成一条新的浏览记录,其 URL 为https://aadonkeyz.com/posts/eb815672/#hash,并将这条新的记录加入到浏览器历史记录的栈顶。与此同时浏览器的浏览状态会跳转到这个最新的记录上。 location.hash改变时,触发了window对象上注册的onhashchange事件处理程序。- 页面内容进行对应的更新。
- 当使用前进或者后退时,会再次触发
onhashchange事件处理程序,页面内容会再次进行相应的更新。 - 前端路由实现。
在 URL 中,# 以及它之后的内容是用于在页面内定位的锚点,它们的改变不会引起浏览器发送网络请求。
history
- 此时浏览器显示的 URL 为
https://aadonkeyz.com。 - 更新页面内容,同时通过
history.pushState()或者history.replaceState()新增/替换浏览器历史记录的栈顶记录,浏览器的浏览状态跳转到栈顶记录上,此时 URL 为https://aadonkeyz.com/posts/eb815672。通过这两个方法,不会触发任何事件,也不会引起浏览器的加载行为。 - 当浏览器前进或后退到某条由
history.pushState()或者history.replaceState()生成的浏览记录时,会触发window对象上注册的onpopstate事件处理程序,并且在事件处理程序的内部,event.state中保存着该浏览记录的状态对象的拷贝。因此可以根据这个event.state更新页面。 - 前端路由实现。
采用这种方式时,为了防止浏览器真的去加载对应的 URL,从而返回 404 Not Found 的尴尬局面,需要服务器的支持,如果 URL 匹配不到任何静态资源,则应该返回根页面 HTML。
更多
「前端进阶」彻底弄懂前端路由 中对前端路由进行了简单的实现,感兴趣的可以阅读一下。如果想更细致的了解前端路由的实现方式,可以阅读 react-router 或者 vue-router 的源码。