路由的分类
- 前端路由(spa)
对于前端路由来说,路由的映射函数通常是进行一些DOM的显示和隐藏操作 - 后端路由 (jsp,,freemark等)
后端路由又称为服务器端路由,对于服务器来说,当接收到客户端发来的http请求,就会根据所请求的相应的映射函数,然后执行该函数,并将函数的返回值发送给客户端。对于最简单的静态资源服务器,可以认为,所有URL的映射函数就是一个文件读取操作。对于动态资源,映射函数可能是一个数据库读取操作,也可能是进行一些数据的处理,等等。然后分局这些读取的数据,在服务器端就使用相应的模板来对页面进行渲染后,再返回渲染完毕的页面(模板引擎,JSP,Freemark等等)。这种方式在早期的前端开发中非常普遍,比如京东页面就是个后端路由,它请求的就是一个页面。
优缺点
- 前端路由
- 优点
- 没有网络延迟,无卡顿
- 缺点
- 用户体验差(后退键的时候会重新发送请求)
- 没有合理利用缓存
- 不利于SEO
- 后端路由
- 优点
- 安全性好
- 利于SEO.
- 缺点
- 加大服务器的压力(模板引擎渲染,流量增加),不利于用户体验
- 代码冗余,前后端耦合度大
- 前端路由的实现方式
-
hash
地址栏中包含一个#,hash 虽然出现在 URL 中,但#之后的内容不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。- 实现原理
监听这个哈希路由改变的事件,渲染相对应的页面元素
- 实现原理
-
history Api
不怕前进和后退,就怕刷新,刷新的时候,如果服务器中没有相应的响应或者资源,则会刷新出来404页面- 实现原理
靠对window.history的操作。这个api有个特点,就是往history里push路由,会跳到相应路由,但没有监听函数,而回退操作却有监听函数。
history 这个对象在html的时候新加入两个api history.pushState() 和 history.repalceState()这两个 API可以在不进行刷新的情况下,操作浏览器的历史纪录。唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录,window.history.pushState(state,title,url) // state:需要保存的数据,这个数据在触发popstate事件时,可以在event.state里获取 // title:标题,基本没用,一般传null // url:设定新的历史纪录的url。新的url与当前url的origin必须是一样的,否则会抛出错误。url可以时绝对路径,也可以是相对路径。 // 如 当前url是 https://www.baidu.com/a/,执行history.pushState(null, null, './qq/'),则变成 https://www.baidu.com/a/qq/, // 执行history.pushState(null, null, '/qq/'),则变成 https://www.baidu.com/qq/ window.history.replaceState(state,title,url) // 与pushState 基本相同,但她是修改当前历史纪录,而 pushState 是创建新的历史纪录 // 此外还有这些方法 window.history.back()//后退 window.history.forward()//前进 window.history.go(1)//前进一部,-2回退两不,window.history.length可以查看当前历史堆栈中页面的数量 // 仅仅调用pushState方法或replaceState方法,并不会触发该事件,只有用户点击浏览器后退和前进按钮时,或者使用js调用back、forward、go方法时才会触发。 window.addEventListener('popstate', function(event) {});
- 监听pushState和replaceState
//创建全局事件 var callback= function(type) { var his= history[type]; return function() { var e = new Event(type); e.arguments = arguments; window.dispatchEvent(e); return his.apply(this, arguments); }; }; //重写方法 history.pushState = callback('pushState'); history.replaceState = callback('replaceState'); //实现监听 window.addEventListener('replaceState', function(e) { console.log('replaceState'); }); window.addEventListener('pushState', function(e) { console.log('pushState'); });
- 实现原理
-