路由浅析

94 阅读3分钟

路由

前端路由

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传值,路由参数传值)