1.什么是路由
简单举例说明,假如我们有一台提供 Web 服务的服务器的网络地址是:10.0.0.1,而该 Web 服务又提供了三个可供用户访问的页面,其页面 URI 分别是:
http://10.0.0.1/
http://10.0.0.1/about
http://10.0.0.1/concat
那么其路径就分别是 /,/about,/concat。
当用户使用 http://10.0.0.1/about 来访问该页面时,Web 服务会接收到这个请求,然后会解析 URL 中的路径 /about,在 Web 服务的程序中,该路径对应着相应的处理逻辑,程序会把请求交给路径所对应的处理逻辑,这样就完成了一次「路由分发」,这个分发就是通过「路由」来完成的。
以前路由都是后台做的,通过用户请求的url导航到具体的html页面,前端路由就是通过配置js文件,把这个工作拿到前端来做。
简单的说,路由是根据不同的 url 地址展示不同的内容或页面
2.前端路由
前端的路由和后端的路由在实现技术上不一样,但是原理都是一样的。在 HTML5 的 history API 出现之前,前端的路由都是通过 hash 来实现的,hash 能兼容低版本的浏览器。如果我们把上面例子中提到的 3 个页面用 hash 来实现的话,它的 URI 规则中需要带上 #。
1http://10.0.0.1/2http://10.0.0.1/#/about3http://10.0.0.1/#/concat
Web 服务并不会解析 hash,也就是说 # 后的内容 Web 服务都会自动忽略,但是 JavaScript 是可以通过 window.location.hash 读取到的,读取到路径加以解析之后就可以响应不同路径的逻辑处理。
history 是 HTML5 才有的新 API,可以用来操作浏览器的 session history。基于 history 来实现的路由可以和最初的例子中提到的路径规则一样。
1http://10.0.0.1/2http://10.0.0.1/about3http://10.0.0.1/concat
具体如何实现前端路由将在后面的文章中介绍。
3.前端路由的使用场景?
前端路由更多用在单页应用上, 也就是SPA, 因为单页应用, 基本上都是前后端分离的, 后端自然也就不会给前端提供路由。
4.前端路由优缺点
优点:
1.从性能和用户体验的层面来比较的话,后端路由每次访问一个新页面的时候都要向服务器发送请求,然后服务器再响应请求,这个过程肯定会有延迟。而前端路由在访问一个新页面的时候仅仅是变换了一下路径而已,没有了网络延迟,对于用户体验来说会有相当大的提升。
2.在某些场合中,用ajax请求,可以让页面无刷新,页面变了但Url没有变化,用户就不能复制到想要的地址,用前端路由做单页面网页就很好的解决了这个问题
缺点:
使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存。
1、路由就是用来跟后端服务器进行交互的一种方式,通过不同的路径,来请求不同的资源,请求不同的页面是路由的其中一种功能。
if(path='./xxx'){
do something
}
2、路由实现的两种方式
在现在这些MVC和MVVM框架兴起之前,是不存在前端路由的,页面之间的跳转是由后台控制的。随着前后端分离和单页面应用(SPA)的兴起和WEB项目复杂度的增加,再加上前面这些框架的支持,慢慢前端路由也就成为了现实。单页面应用的特点就是可以在改变URL在不重新请求页面的情况下更新页面视图。
"更新视图但不重新请求页面"是前端路由的原理的核心之一,目前在浏览器环境中这一功能的实现主要有两种方式
利用URL中的hash("#")
利用History interface在 HTML5中新增的方法
hash
这是的hash不是指的是数据结构中的hash表,而是类似https://juejin.im/#123gqwf,通过监听a标签,这样#号后面值的变化并不会发送请求也不会刷新页面,并且会触发windo.onhashchange事件。
pushState
html5新增加的api,History.pushState()History.replaceState(),这两个api也能改变url并且不发送请求,而且比#好看,原理也是相同的,但是如果用户刷新页面,也会发送请求,返回404,所以需要后端配合,如果用户刷新页面,把所有的无响应的路由重定向到根目录
3、vue-router实现前端路由的方法和对比
在vue-router中有mode这样一个参数,这个参数的可选值有"hash"、 "history"、"abstract"
const router = new VueRouter({
mode: 'history',
routes: [...]
})
那"hash"和"history"这两种方式各有什么优劣呢?
首先在vue-router中默认使用的是hash这种方式,因为这种方式虽然带个#有点丑(官方竟然都这样说),但是不存在兼容性问题
而history由于底层的实现根据MDN的介绍,调用history.pushState(),所以存在浏览器兼容性问题。
如果不考虑兼容性问题的话,pushState肯定比只修改hash值更加强大,因为可以设置任意同源URL
pushState可以设置和当前URL一模一样,这样也会把记录添加到栈中,而hash设置的新值必须和原来不一样
还有,就算不考虑兼容问题的话,history模式还有一个问题,就是history模式会将URL修改的和正常请求后端的URL一样
http://oursite.com/user/id
这样的话如果后端没有配置对应的user/id这样一个地址的话就会返回404,官方推荐的解决办法是在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。同时这么做以后,服务器就不再返回 404 错误页面,因为对于所有路径都会返回 index.html 文件。为了避免这种情况,在 Vue 应用里面覆盖所有的路由情况,然后在给出一个 404 页面。(这种方案我还没实践过,有机会要实践一下)
所以综合考虑来说用在一些中后台项目中的话一般直接就采用hash这种默认方式了,而前台项目的话看需求选择使用history还是hash