前端路由---hash,history两种模式

SPA(单页面应用)需要在不刷新页面的情况下做页面更新的能力,这就需要引入前端路由,实际上,前端路由是利用了浏览器的hash或history属性。

一、什么是路由

1、路由用途解释:随浏览器地址的变化,展示给用户看到的页面也不同。
2、路由实现原理解释:URL到函数的映射

二、路由又分前端路由和后端路由:

  1. 后端路由: 又称服务器端路由,当服务器收到客户端发来的HTTP请求,就会根据请求的URL,来找到相应的映射函数,然后执行该函数,将执行结果的返回值发送给客户端。
    对于最简单的静态资源服务器,可以认为,所有的URL的映射函数就是一个文件读取操作。而对于动态资源,映射函数可能是一个数据库读取操作,也可能是进行一些数据操作,等等。然后根据读取的数据,在服务器端就使用相应的模块来对页面进行渲染后,再返回渲染完毕的页面。这种方式在早期的前端开发中非常普遍,像京东的页面就是一个后端路由,他请求的是一个页面。
    优点:安全性好,SEO好。
    缺点:加大服务器的压力,不利于用户体验,代码冗合。

  2. 前端路由: URL到函数的映射。路由的映射函数通常是进行一些DOM的显示隐藏操作。当访问不同路径时,就会显示不同的页面组件。
    优点:访问不同页面时,仅仅只是变换了路径而已,没有网络延迟,提升了用户体验。
    缺点:使用浏览器的前进后退时,会重新发送请求,没有合理的利用缓存,不利于SEO。

三、前端路由主要有两种实现方案:hash、history API

1、Hash的实现原理

hash实现就是基于location.hash来实现的,早期前端路由都是用hash。location.hash的值就是URL中#后面的内容。比如百度网站设置他的location.hash=’#abc’,那么他的网址就是https://www.baidu.com/#abc。

1.1:hash特性:
①、 URL中hash值只是客户端的一种状态,即当客户端向服务器端发送请求时,hash部分是不会被发送的,对后端无影响所以改变hash不会重新加载啊页面。
②、 每次hash值发送改变,都会在浏览器的访问历史中新增一个记录,所以我们可以操作浏览器前进回退,其实就是操作前进回退按钮去控制hash值的切换。
③、 使用hashchange事件来监听hash的变化。还可以通过history.length看到路由总数。
④、 Hash本身用作页面定位(锚点),用作路由后后锚点功能就没有了,hash传参基于URL,数据量大时会有体积限制,在导航栏会出现很丑的‘#’

1.2:hash的使用
①、 使用a标签,设置href属性,点击后URL就会发生变化,触发hashchange事件。

<a href=‘#test’>test</a>

②、 使用js对location.hash进行赋值,来改变URL触发hashchange事件。

location.hash=‘#test’

举例:hash方案实现路由切换 —监听事件hashchange

window.addEventListener("hashchange", function() { 
// 获取hash值 
var hash = window.location.hash; 
// 根据获取的hash做相应的操作
 . . . 
window.location.hash = "#hahah"; 
// 变成http://www.bbbb.com#hahah
});

每当hash发生改变都会触发hashchange方法,但是注意,浏览器刷新,页面跳到首页,URL不会改变。

2、history API 的实现原理

更美观的实现URL的变化,由H5提供的history API。最主要的API:history.pushState()、history.replaceState()。这两个API可以在不刷新的情况下,操作浏览器的历史记录。区别:pushState()是会增加新的历史记录,而replaceState()是替换当前的历史记录。都接受三个参数(state,title,URL)

1.1、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 是创建新的历史纪录

1.2、其他API -----触发监听

window.history.back(); // 后退
window.history.forward(); // 前进
window.history.go(1); // 前进一部,-2回退两不,window.history.length可以查看当前历史堆栈中页面的数量

1.2、history API的使用 — popState()事件监听

window.addEventListenner(‘popstate’,function(event){
	// 监听浏览器前进后退事件,pushState 与 replaceState 方法不会触发
});

注意:仅仅调用pushSatte()和replaceState()去改变URL是不会触发事件监听的,需要另外点击前进后退按钮才触发,即调用back()、go()等API

怎么确实监听pushSatte()和replaceState()?
可以创建2个全新的事件,事件名为pushState和replaceState,我们就可以在全局监听。

//创建全局事件
var _wr = function(type) {   
	var orig = history[type];   
	return function() {       
		var rv = orig.apply(this, arguments);      
		var e = new Event(type);       
		e.arguments = arguments;       
		window.dispatchEvent(e);       
		return rv;   
	};
};
//重写方法 
history.pushState = _wr('pushState'); 
history.replaceState = _wr('replaceState');
//实现监听
window.addEventListener('replaceState',function(e){  
	console.log('THEYDIDITAGAIN!replaceState111111');
});
window.addEventListener('pushState',function(e){  
	console.log('THEYDIDITAGAIN!pushState2222222');
});

1.3、hash和history的区别

  1. hash--------------history
  2. 兼容更好--------------更正式美观
  3. 只修改#后面内容--------------可以设置同源下任意URL
  4. 新值不能与旧值相同,一样的不会触发动作将记录添加到栈中--------------新旧值可以相同,pushSate该添加的会添加到栈中
  5. 对服务器无需改动--------------刷新时,若服务器没有响应数据或资源,会404。需要对服务器做一些改造,对不同的路由进行相应的设置。
  6. 即不会发送请求--------------会向服务器发送请求,避免404服务器应该做处理。当匹配不到资源时,应返回同一个html页面
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值