前端路由定义
路由的概念来源于服务端,在服务端中路由描述的是URL与处理函数之间的映射关系。
在Web前端单页应用SPA中,路由描述的是URL与UI之间的映射关系,这种映射是单向的,无需刷新页面。
前端路由包括两种方式:
hash模式、history模式
hash模式
定义:URL的hash 是以#开头,是基于location.hash来实现的。Location.hash的值就是URL中#后面的内容。当hash改变时,页面不会刷新,浏览器也不会请求服务器。但是可以通过 hashchange 事件监听URL的变化。
改变URL的方式有以下方法:
- 通过浏览器前进后退改变URL
- 通过a标签改变URL
- 通过window.location改变URL
history模式
定义:history API 是 H5 提供的新特性,history提供了pushState和replaceState两个方法,这两个方法改变URL的path部分不会引起页面刷新。
pushState: 需要三个参数:一个状态对象, 一个标题(目前被忽略), 和一个URL
- state, 状态对象state是一个JavaScript对象,popstate事件触发时,该对象会传入回调函数
- title, 目前所有浏览器忽略
- url, 新的url记录
replaceState: history.replaceState()的使用与history.pushState()非常相似,区别在于replaceState()是修改了当前的历史记录项而不是新建一个。
onpopstate: 需要特别注意的是,调用history.pushState()或history.replaceState()不会触发popstate事件。只有在做出浏览器动作时,比如点击后退、前进按钮【或者调用JS中的history.back()、history.forward()、history.go()】才会触发该事件。
history 提供类似 hashchange 事件的 popstate 事件,但 popstate 事件有些不同:通过浏览器前进后退改变 URL 时会触发 popstate 事件,通过pushState/replaceState或a标签改变 URL 不会触发 popstate 事件。好在我们可以拦截 pushState/replaceState的调用和a标签的点击事件来检测 URL 变化,所以监听 URL 变化可以实现,只是没有 hashchange 那么方便。
hash模式与history模式对比
hash 优缺点:
优点:
- 实现简单,兼容性好(兼容到ie8)
- 绝大多数前端框架均提供了给予hash的路由实现
- 不需要服务器端进行任何设置和开发
- 除了资源加载和ajax请求以外,不会发起其他请求
缺点:
- 对于部分需要重定向的操作,后端无法获取hash部分内容,导致后台无法取得url中的数据,典型的例子就是微信公众号的oauth验证
- 服务器端无法准确跟踪前端路由信息
- 对于需要锚点功能的需求会与目前路由机制冲突
history模式优缺点:
优点
- 对于重定向过程中不会丢失url中的参数。后端可以拿到这部分数据
- 绝大多数前段框架均提供了browser的路由实现
- 后端可以准确跟踪路由信息
- 可以使用history.state来获取当前url对应的状态信息
缺点
- 兼容性不如hash路由(只兼容到IE10)
- 需要后端支持,每次返回html文档