前端路由理解
前端路由在很多开源的js类库框架中都得到支持,如angular,react等。
一、路由(route)
定义
路由是url到函数的映射,可以根据不同的url地址展示不同的内容或页面。
/users -> getAllUsers()
/users/count -> getUsersCount()
这就是两条路由,当访问 /users 的时候,会执行 getAllUsers() 函数;当访问 /users/count 的时候,会执行 getUsersCount() 函数。
router
是一个容器,或机制,管理了一组route。简单来说,route 只是进行了URL和函数的映射,而在当接收到一个URL之后,去路由映射表中查找相应的函数,这个过程是由 router 来处理的。一句话概括就是 “The router routes you to a route”。
二、服务器端路由(后端路由)
对于服务器来说,当接收到客户端发来的HTTP请求,会根据请求的URL,来找到相应的映射函数,然后执行该函数,并将函数的返回值发送给客户端。对于最简单的静态资源服务器,可以认为,所有URL的映射函数就是一个文件读取操作。对于动态资源,映射函数可能是一个数据库读取操作,也可能是进行一些数据的处理,等等。
在 router 匹配 route 的过程中,不仅会根据URL来匹配,还会根据请求的方法来看是否匹配。例如上面的例子,如果通过 POST 方法来访问 /users,就会找不到正确的路由。
早期的路由都是后端实现的,直接根据 url 来 reload 页面,页面变得越来越复杂服务器端压力变大,随着 ajax 的出现,页面实现非 reload 就能刷新数据,可以通过记录 url 来记录 ajax 的变化,从而实现前端路由。
三、客户端路由(前端路由)
对于客户端(通常为浏览器)来说,路由的映射函数通常是进行一些DOM的显示和隐藏操作。这样,当访问不同的路径的时候,会显示不同的页面组件。客户端路由最常见的有以下两种实现方案。
基于history API
在 HTML5 规范中,history 新增了以下几个 API,能做到:改变 url 的同时,不会刷新页面。
history.pushState(); // 添加新的状态到历史状态栈
history.replaceState(); // 用新的状态代替当前状态
接收三个参数,分别是:
- 状态对象(state object) — 一个JavaScript对象,与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,popstate事件都会被触发,并且事件对象的state属性都包含历史记录条目的状态对象的拷贝。
- 标题(title) — FireFox浏览器目前会忽略该参数,虽然以后可能会用上。考虑到未来可能会对该方法进行修改,传一个空字符串会比较安全。或者,你也可以传入一个简短的标题,标明将要进入的状态。
- 地址(URL) — 新的历史记录条目的地址。浏览器不会在调用pushState()方法后加载该地址,但之后,可能会试图加载,例如用户重启浏览器。新的URL不一定是绝对路径;如果是相对路径,它将以当前URL为基准;传入的URL与当前URL应该是同源的,否则,pushState()会抛出异常。该参数是可选的;不指定的话则为文档当前URL。
基于hash
url上的hash本来是锚点(#),方便用户在很长的文档中进行上下文导航,且hash有一种特性:改变url的同时不刷新页面,浏览器用onhashchange
事件监听hash的变化。
优缺点
- hash路由兼容性更好,不需对服务器做改动
- history API更直观和正式,需要对服务器进行改造
四、动态路由
静态路由是路径固定的路由,但是有时候需要在路径中传入参数,例如获取某个用户的信息,不可能为每个用户创建路由,而是通过捕获路径中的参数(例如用户id)来实现,这就是动态路由。
参考:
什么是前端路由
前端路由的两种实现
理解web路由
单页面应用路由实现原理:以 React-Router 为例
浅谈前端路由
下一篇: 使用Matplotlib绘制3D动图