前端路由

2019-11-01 | 12分钟 | yrobot | 路由,前端

前世今生

很久以前,一个 web 网站,是由很多 html 组成的,俗称多页面。
前端对于每个路由实现一个 html,并将 html 部署到服务器作为对应路由的返回内容,这样 host/a 就返回 a.html,host/b 就返回 b.html,修改请求 url,服务器返回对应 html 并展示,实现项目间页面的跳转。
可以看出,这样的模式,前端实现很麻烦(要多写很多 html,大部分内容还都是重复的,比如 tabBar),部署还需要运维支持,对每个路由 url 请求进行对应 html 的配置。

然后,SPA(single page application)诞生了。
单页面应用,很直白的表示了,这个应用只有一个页面。而原本不同页面的内容通过修改这个页面的展示组件去操控。
但是 SPA 有个很大的问题,就是怎么控制应用展示那个页面。
于是乎,前端路由横空出世。

前端路由需要做什么

正如上面说分析的,
前端路由最重要的就是告诉 SPA 应该展示什么页面,但是又不能触发后端请求。
简而言之
前端路由的核心: 改变页面视图的同时不会向后端发出请求

没有路由系统的 SPA 的弊端

  1. 用户在使用过程中,url 不会发生变化,那么用户在进行多次跳转之后,如果一不小心刷新了页面,又会回到最开始的状态,用户体验极差。
  2. 由于缺乏路由,不利于 SEO(搜索引擎优化),搜索引擎进行收录。

前端路由的实现

hash 路由

原理
url 上的 hash 以 # 开头,原本是为了作为锚点,方便用户在文章导航到相应的位置。因为 hash 值的改变不会引起页面的刷新,于是就想到用 hash 值来做单页面应用的路由。当 url 的 hash 发生变化的时候,可以触发相应 hashchange 回调函数来控制页面内容的更新。

优势:

  1. 用 hash 在做路由跳转的好处在于简单实用,便于理解

缺点:

  1. url 却引入 # 号,不够美观。
  2. 在一些调用三方登陆服务时,传回的 url 参数位置在#前的问题从而引起读不到 hash 参数的问题

History 路由

原理:
基于 HTML5 规范,在 HTML5 规范中提供了 history.pushState、history.replaceState 来进行展示路由控制,并且不触发页面刷新和请求。
那么我们只要利用 history API 更新展示的 url,同时手动更新页面内容,从而实现路由的功能。
而对于首次打开,只需在路由 constructor 里读取 path 并更新页面内容即可。

pushState 逻辑:
假设在 http://mozilla.org/foo.html 中执行了以下 JavaScript 代码:

let stateObj = {
    foo: "bar",
};
history.pushState(stateObj, "page 2", "bar.html");

这将使浏览器地址栏显示为 http://mozilla.org/bar.html ,但并不会导致浏览器加载 bar.html ,甚至不会检查 bar.html 是否存在。

优势:

  1. url 简洁美观

缺点:

  1. 刷新时,会用对应路由 url 请求服务器,如果服务器不做处理,就会报 404