路由
到底什么是路由呢?简单来说,路由就是 URL 到函数的映射。
在以前用模板引擎开发页面的时候,是使用路由返回不同的页面,大致流程是这样的:
-
浏览器发出请求;
-
服务器监听到 80 或者 443 端口有请求过来,并解析 UR L路径;
-
服务端根据路由设置,查询相应的资源,可能是 html 文件,也可能是图片资源......,然后将这些资源处理并返回给浏览器;
-
浏览器接收到数据,通过
content-type
决定如何解析数据
简单来说,路由就是用来跟后端服务器交互的一种方式,通过不同的路径来请求不同的资源,请求HTML
页面只是路由的其中一项功能。
服务端路由
当服务端接收到客户端发来的 HTTP 请求时,会根据请求的 URL,找到相应的映射函数,然后执行该函数,并将函数的返回值发送给客户端。
对于最简单的静态资源服务器,可以认为,所有 URL 的映射函数就是一个文件读取操作。对于动态资源,映射函数可能是一个数据库读取操作,也可能进行一些数据处理,等等。
客户端路由
服务端路由会造成服务器压力比较大,而且用户访问速度也比较慢。在这种情况下,出现了单页应用。
单页应用,就是只有一个页面,用户访问网址,服务器返回的页面始终只有一个,不管用户改变了浏览器地址栏的内容或者在页面发生了跳转,服务器不会重新返回新的页面,而是通过相应的js操作来实现页面的更改。
前端路由其实就是:通过地址栏内容的改变,显示不同的页面。
前端路由的优点:
-
前端路由可以让前端自己维护路由与页面展示的逻辑,每次页面改动不需要通知服务端。
-
更好的交互体验:不用每次从服务端拉取资源。
前端路由的缺点: 使用浏览器的前进、后退键时会重新发送请求,来获取数据,没有合理利用缓存。
前端路由实现原理: 本质就是监测 URL 的变化,通过拦截 URL 然后解析匹配路由规则。
前端路由的实现方式
1.hash事件
location.hash + hashchange 事件
hash 模式的实现方式就是通过监听 URL 中的 hash 部分的变化,触发haschange
事件,页面做出不同的响应。 hash 模式下,URL 中会带有 #。
2.history模式
-
history.go()
:在会话历史中向前或者向后移动指定页数 -
history.forward()
:在会话历史中向前移动一页 -
history.back()
:在会话历史记录中向后移动一页 -
history.pushState()
:向当前浏览器会话的历史堆栈中添加一个状态,会改变当前页面url,但是不会伴随刷新 -
history.replaceState()
:将当前的会话页面的url替换成指定的数据,replaceState 会改变当前页面的url,但也不会刷新页面 -
window.onpopstate
:当前活动历史记录条目更改时,将触发popstate
事件
history路由的实现,主要是依靠pushState
、replaceState
和window.onpopstate
实现的。但是有几点要注意:
-
当活动历史记录条目更改时,将触发 popstate 事件;
-
调用
history.pushState()
或history.replaceState()
不会触发 popstate 事件 -
popstate 事件只会在浏览器某些行为下触发,比如:点击后退、前进按钮(或者在 JavaScript 中调用
history.back()
、history.forward()
、history.go()
方法) -
a 标签的锚点也会触发该事件