一、什么是路由?
路由的概念起源于服务端,在以前前后端不分离的时候,由后端来控制路由,当接收到客户端发来的 HTTP 请求,就会根据所请求的相应 URL,来找到相应的映射函数,然后执行该函数,并将函数的返回值发送给客户端。对于最简单的静态资源服务器,可以认为,所有 URL 的映射函数就是一个文件读取操作。对于动态资源,映射函数可能是一个数据库读取操作,也可能是进行一些数据的处理等等。然后根据这些读取的数据,在服务器端就使用相应的模板来对页面进行渲染后,再返回渲染完毕的页面。它的好处与缺点非常明显:
-
好处:安全性好,
SEO好; -
缺点:加大服务器的压力,不利于用户体验,代码冗合不好维护;
也正是由于后端路由还存在着自己的不足,前端路由才有了自己的发展空间。对于前端路由来说,路由的映射函数通常是进行一些 DOM 的显示和隐藏操作。这样,当访问不同的路径的时候,会显示不同的页面组件。前端路由主要有以下两种实现方案:
HashHistory
二、前端路由Hash模式
一个URL是由很多部分组成,包括协议、域名、路径、query、hash等,早期的前端路由的实现就是基于location.hash来实现的。其实现原理也很简单,location.hash的值就是URL中#后面的内容。 例如:www.WDNMD.com#666, 它的location.hash='#666'
Hash模式的特性:
-
URL中hash值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash部分不会被发送。
-
hash值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash的切换。
-
我们可以使用hashchange事件来监听hash的变化。(a标签和对loaction.hash进行赋值等等)
通过上面的了解,我们大概知道这些
-
hash模式所有的工作都是在前端完成的,不需要后端服务的配合
-
hash模式的实现方式就是通过监听URL中hash部分的变化,从而做出对应的渲染逻辑
-
hash模式下,URL中会带有#,看起来不太美观
因此Hash模式还是有些小小的不足,History API也就出现了
-
三、前端路由History API模式
history路由模式的实现,是要归功于HTML5提供的一个history全局对象,可以将它理解为其中包含了关于我们访问网页(历史会话)的一些信息。window.history 属性指向 History 对象,它表示当前窗口的浏览历史。当发生改变时,只会改变页面的路径,不会刷新页面。 History 对象保存了当前窗口访问过的所有页面网址。通过 history.length 可以得出当前窗口一共访问过几个网址。 由于安全原因,浏览器不允许脚本读取这些地址,但是允许在地址之间导航。 浏览器工具栏的“前进”和“后退”按钮,其实就是对 History 对象进行操作。
同时它还暴露了一些有用的方法,比如:
- window.history.go 可以跳转到浏览器会话历史中的指定的某一个记录页
- window.history.forward 指向浏览器会话历史中的下一页,跟浏览器的前进按钮相同
- window.history.back 返回浏览器会话历史中的上一页,跟浏览器的回退按钮功能相同
- window.history.pushState 可以将给定的数据压入到浏览器会话历史栈中
- window.history.replaceState 将当前的会话页面的url替换成指定的数据
而history路由的实现,主要就是依靠于pushState与replaceState实现的
总结
hash
原理
在 url 中的 # 之后对应的是 hash 值, 其原理是通过hashChange() 事件监听hash值的变化, 根据路由表对应的hash值来判断加载对应的路由加载对应的组件
优点
- 只需要前端配置路由表, 不需要后端的参与
- 兼容性好, 浏览器都能支持
- hash值改变不会向后端发送请求, 完全属于前端路由
缺点
- hash值前面需要加#, 不符合url规范,也不美观
分析
当 URL 改变时,页面不会重新加载。 hash(#)是URL 的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器
只会滚动到相应位置,不会重新加载网页,也就是说 #是用来指导浏览器动作的,对服务器端完全无用,HTTP请求中也不会不包括#;同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;所以说Hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据
history
优点
- 符合url地址规范, 不需要#, 使用起来比较美观
缺点
- 在用户手动输入地址或
刷新页面时会发起url请求, 后端需要配置index.html页面用户匹配不到静态资源的情况, 否则会出现404错误 - 兼容性比较差, 是利用了 HTML5 History对象中新增的 pushState() 和 replaceState() 方法,需要特定浏览器的支持.
参考文章: