前端路由的基础理解

423 阅读5分钟

一、什么是路由?

路由的概念起源于服务端,在以前前后端不分离的时候,由后端来控制路由,当接收到客户端发来的 HTTP 请求,就会根据所请求的相应 URL,来找到相应的映射函数,然后执行该函数,并将函数的返回值发送给客户端。对于最简单的静态资源服务器,可以认为,所有 URL 的映射函数就是一个文件读取操作。对于动态资源,映射函数可能是一个数据库读取操作,也可能是进行一些数据的处理等等。然后根据这些读取的数据,在服务器端就使用相应的模板来对页面进行渲染后,再返回渲染完毕的页面。它的好处与缺点非常明显:

  • 好处:安全性好,SEO 好;

  • 缺点:加大服务器的压力,不利于用户体验,代码冗合不好维护;

也正是由于后端路由还存在着自己的不足,前端路由才有了自己的发展空间。对于前端路由来说,路由的映射函数通常是进行一些 DOM 的显示和隐藏操作。这样,当访问不同的路径的时候,会显示不同的页面组件。前端路由主要有以下两种实现方案:

  • Hash
  • History

二、前端路由Hash模式

一个URL是由很多部分组成,包括协议、域名、路径、query、hash等,早期的前端路由的实现就是基于location.hash来实现的。其实现原理也很简单,location.hash的值就是URL中#后面的内容。 例如:www.WDNMD.com#666, 它的location.hash='#666'

Hash模式的特性:

  1. URL中hash值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash部分不会被发送。

  2. hash值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash的切换。

  3. 我们可以使用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() 方法,需要特定浏览器的支持.

参考文章:

什么是路由?

vue路由模式及 history 模式下服务端配置