前言
在浏览器中,路由可以简单理解为请求地址,实际上在早些时候,只有后端路由,虽然前端的路由和后端的路由在实现技术上不一样,但是原理都是一样的,都是通过解析路径来进行页面响应,对于 Web 开发来说,路由的实质是 URL 到对应的处理程序的映射
前端路由的使用场景
前端路由更多用在单页应用上, 也就是SPA, 因为单页应用, 基本上都是前后端分离的, 后端自然也就不会给前端提供路由
前端路由的优缺点
优点
- 从性能和用户体验的层面来比较的话,后端路由每次访问一个新页面的时候都要向服务器发送请求,然后服务器再响应请求,这个过程肯定会有延迟。而前端路由在访问一个新页面的时候仅仅是变换了一下路径而已,没有了网络延迟,对于用户体验来说会有相当大的提升
缺点
使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存
前端路由的分类
前端路由根据实现方式的不同,可以分为 Hash 路由 和 History 路由
Hash 路由
一个 URI 的组成如下所示。其中的 fragment 部分就是 Hash 路由所读取的内容
foo://example.com:8042/over/there?name=ferret#nose _/ ______________/_________/ _________/ __/ | | | | | scheme authority path query fragment | _____________________|__ / \ / \ urn:example:animal:ferret:nose 复制代码
fragment 本质是用来标识次级资源,fragment 有以下特点:
- 修改 fragment 的内容不会触发网页重载。
- 修改 fragment 的内容会改变浏览器的历史记录。
- 修改 fragment 的内容会触发浏览器的 onhashchange 事件。
基于 fragment 的以上特点,可实现基于 Hash 的前端路由。
实现原理
浏览器提供了haschange
事件来监听 hash
的变化,我们可以通过监听 hash 的变化,解析 hash 的值来实现页面的切换
window.addEventListener("hashchange", (e) => { // hash 变化更新页面 // ... }) 复制代码
优缺点
Hash 路由由于通过监听 hash 变化实现,所以有以下优势和不足:
- 优点
兼容性最佳,无需服务端配置
- 缺点
服务端无法获取 hash 部分内容,和锚点功能冲突,影响 SEO
History 路由
Hash 路由是一个相对“Hack”的方式,利用了 fragment 来实现路由功能。而 History 路由则是通过浏览器原生提供的操作 History 的能力来实现的路由功能。
实现原理
History
路由核心主要依赖 History API
里的两个方法和一个事件,其中两个方法用于操作浏览器的历史记录,事件用于监听历史记录的切换:
方法:
- history.pushState:将给定的 Data 添加到当前标签页的历史记录栈中
- history.replaceState:将给定的 Data 更新到历史记录栈中最新的一条记录中
事件:
- popstate:监听历史记录的变化
window.addEventListener("popstate", (e) => { // state 变化更新页面 // ... }); 复制代码
优缺点
- 优点
服务端可以获取完整的链接和参数,前端监控,SEO相对友好
- 缺点
兼容性稍差,需要服务端额外配置