路由
前端路由
1.传统路由
路由: URL(统一资源定位符: developer.mozilla.org/zh-CN/docs/…)
传统的web开发模式里面,路由都是由服务器控制的,根据url映射不同的页面(资源)
传统路由的缺陷:
- 重复的资源请求
- 响应较慢,页面刷新,导致用户体验下降
2.前端路由
前端根据不同的url,切换到不同的页面(page组件);每个页面根据需要去服务端获取数据,从而避免了重复的资源请求
前端会记录路由的状态,包括历史记录,即使是刷新和回退,都能够定位到具体的路由对应的页面,从而实现更好的交互体验
实现前端前端路由的需要解决的问题:
- 如何改变url,不引起页面刷新
- 如何监听路由变化,以及根据路由渲染对应的页面(路由和组件匹配规则)
- 如何记录路由的状态
两种方式:
- hash的方式来实现
- 通过HTML5的history的pushState\replaceState方法实现
3.react-router实现路由的机制
- 借助history库,history中实现了push, go, goBack等方法,注册了hashChange事件,当路由跳转时,使用浏览器内置的history api操作history栈 改变
- history库对外暴露的history对象提供了listen方法,组件会注册一个listener 监听
- 当调用history.push或hashChange事件触发时,执行listener
- 注册的监听函数内部会setState更新状态,通过context.Provider的value将路由信息传递给 渲染
- 的子组件的中context.Consumer接受value,根据当前的path和浏览器的当前的location来判断当前route是否match,匹配渲染component 渲染
-
hashRouter(hashHistory)
-
1.hash的特点
- 特点: 出现在url中,但是不会包括在HTTP请求中,hash的改变不会重新加载页面,可以通过wondow.hashchange监听hash的变化
browserRouter(broswerHistory)
1.HTML5的history特点
属性和方法
- history.length: 返回在会话历史中有多少条记录,包含了当前的会话页面.比如打开一个新的Tab,那么length的值为0;
- history.pushState(stateObj,title,url): history中添加一条记录
- history.replaceState(stateObj,title,url): hisotry中替换当前记录,history的长度不会改变
- history.go(),history.back()...
特点:
history.pushState和history.replaceState可以在不刷新的情况下改变url的地址(保存状态的一个作用);如果页面发生回退back或者forward的时候,会触发popState事件
4.需要结合后端配置
broswerHistory模式下,URL是指向真实URL的资源路径,当通过真实URL访问网站的时候(首页),这个时候可以正常的加载我们的网站资源,而非首页下手动刷新页面时,由于路径是指向服务器的真是路径,但是该路径下并没有相关的资源,而用户访问的资源不存在,返回给用户的是404错误
方法1: 后端白名单
缺点: 增加一个路由,白名单就需要修改,而且针对的动态路由无法生效
方法2: 使用服务端的404页面,直接将404.html的内容弄成和index内容一样
方法3: 官方做法(github.com/reactjs/rea…)
hashRouter和browserRouter的对比
区别:
- broswerRouter模式下,URL是指向真实URL的资源路径,当通过真实URL访问网站的时候(首页),这个时候可以正常的加载我们的网站资源,而非首页下手动刷新页面时,由于路径是指向服务器的真实路径,但是该路径下并没有相关的资源,而用户访问的资源不存在,返回给用户的是404错误,所以需要后端配合
- hashRouter的兼容性更好,一般旧的浏览器(IE8,IE9)会选择使用hashRouter
- 路由参数方式不同: browserRouter有三种方式(url传值,路由参数传值,以及state),hashRouter有两种方式(url传值,路由参数传值)