前端路由解析(二) —— history路由

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 前端路由解析(二) —— history路由

640.jpg

写在前面


现在的前端应用很多都是单页应用。路由对于单页应用来说,是一个重要的组成部分。本系列文章将讲解前端路由的实现原理。这是系列文章的第二篇:history路由。


系列文章第一篇:前端路由解析(一) ——  hash路由


history api


HTML5引入了history.pushStatehistory.replaceState方法,他们分别可以添加和修改历史记录条目。pushStatereplaceState都接收三个参数:

  1. state: 一个JS对象。在popstate事件中使用。
  2. title: 标题。一般浏览器都忽略这个参数。
  3. url:  任意url,可以是相对路径,也可以是绝对路径。但是必须与当前url同源。

一个pushState的例子,假如我们在https://www.google.com/执行以下代码:


let stateObj = {    foo: "bar",};
history.pushState(stateObj, "page 2", "bar.html");


浏览器的地址栏将变成:https://www.google.com/bar.html

但是,浏览器并不会刷新。此时,history.state的值为:{foo: "bar"}

我们点击浏览器的后退按钮,浏览器会重新回到https://www.google.com/

replaceStatepushState的用法一样,仅有一处不同:

history.pushState是在保留当前记录记录的基础上,再添加一个新的url。而history.replaceState是将当前历史记录替换为新的url。


什么时候会触发popstate事件呢?无论什么时候用户导航到新的状态,popstate事件就会被触发。举个例子,我们在某个页面执行下面的代码:


history.pushState({ page: 1 }, '', 'page1.html');history.pushState({ page: 2 }, '', 'page2.html');


执行完成后,页面会链接为:xxxx/page2.html

此时,点击浏览器后退按钮,页面会回到 xxxx/page1.html,并且会触发一次popstate事件,且事件对象的state参数值为:{ page: 1}。再次点击浏览器历史记录前进按钮,页面回到 xxxx/page2.html,触发一次popstate事件,事件对象的state参数值为:{page : 2}


history路由


history路由就是通过history.pushStatehistory.replaceState 以及 popstate来实现的。我们实现一个最简单的,包含下面两个方面功能:


1、用户点击a标签,可以进行路由跳转。

2、用户点击浏览器的前进后退按钮,可以进行路由跳转。


<html>  <body>      <a href='/p1'>page1</a>      <a href='/p2'>page2</a>      <a href='/p3'>page3</a>      <main>          <div id="content">              这是首页          </div>      </main>  </body>  <script>  window.onload = function () {
    const routerMap = {        '/p1': () => {            document.getElementById('content').innerHTML = '这是段落1111的内容'        },        '/p2': () => {            document.getElementById('content').innerHTML = '这是段落22222的内容'        },        '/p3': () => {            document.getElementById('content').innerHTML = '这是段落33333的内容'        },    };
    const handleRoute = function(inputUrl) {        const url = '/' + inputUrl;        const routeCb = routerMap[url];        if(typeof routeCb === 'function') {            routeCb();        }    }
    window.onpopstate = function (e) {        const url = e.state && e.state.url || '';        url &&  handleRoute(url);    }
    document.addEventListener('click', e => {                if(e.target.tagName !== 'A') return;        e.preventDefault();
        const href = e.target.getAttribute('href');        if(!href) return;
        const url = href.split('/').pop();        window.history.pushState({ url }, null , url);        handleRoute(url);    });  }</script></html>


最终的效果如下:

640.gif


这里需要注意的是,history路由往往需要服务端的配合。虽说 history api 不会刷新页面,但是当用户处在某一个路由并刷新页面时,或者用户直接访问带有路由的页面时,如果服务端没有对当前url进行处理,那么很可能就直接404了。所以需要服务端把相关的url,全都匹配到对应的单页应用的html上。


history路由和hash路由对比


结合之前的hash路由原理,我们可以简单对比一下:


1、history路由比hash路由"长"得好看一下,毕竟url里面带有#看起来不太美观。

2、history路由兼容性不够完美,毕竟是使用了html5标准的api,并且,history路由往往需要服务端的配合。

3、hash路由的兼容性更好。


在实际项目中,根据自己的实际情况来选择使用哪种路由就好了。


写在后面


本文解析了history api,以及history路由的实现原理,符合预期。后续会对react-router的源码进行解析。

相关文章
|
23天前
|
移动开发 缓存 前端开发
深入理解前端路由:原理、实现与应用
本书《深入理解前端路由:原理、实现与应用》全面解析了前端路由的核心概念、工作原理及其实现方法,结合实际案例探讨了其在现代Web应用中的广泛应用,适合前端开发者和相关技术人员阅读。
|
29天前
|
负载均衡 网络协议 定位技术
在数字化时代,利用DNS实现地理位置路由成为提升用户体验的有效策略
在数字化时代,利用DNS实现地理位置路由成为提升用户体验的有效策略。通过解析用户请求的来源IP地址,DNS服务器可判断其地理位置,并返回最近或最合适的服务器IP,从而优化网络路由,减少延迟,提高访问速度。示例代码展示了如何基于IP地址判断地理位置并分配相应服务器IP,实际应用中需结合专业地理数据库和动态调整机制,以应对复杂网络环境带来的挑战。
31 6
|
1月前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
73 1
|
1月前
|
机器学习/深度学习 编解码 前端开发
探索无界:前端开发中的响应式设计深度解析####
【10月更文挑战第29天】 在当今数字化时代,用户体验的优化已成为网站与应用成功的关键。本文旨在深入探讨响应式设计的核心理念、技术实现及最佳实践,揭示其如何颠覆传统布局限制,实现跨设备无缝对接,从而提升用户满意度和访问量。通过剖析响应式设计的精髓,我们将一同见证其在现代Web开发中的重要地位与未来趋势。 ####
46 7
|
1月前
|
编解码 前端开发 UED
探索无界:前端开发中的响应式设计深度解析与实践####
【10月更文挑战第29天】 本文深入探讨了响应式设计的核心理念,即通过灵活的布局、媒体查询及弹性图片等技术手段,使网站能够在不同设备上提供一致且优质的用户体验。不同于传统摘要概述,本文将以一次具体项目实践为引,逐步剖析响应式设计的关键技术点,分享实战经验与避坑指南,旨在为前端开发者提供一套实用的响应式设计方法论。 ####
64 4
|
1月前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
66 1
|
1月前
|
前端开发 JavaScript 开发者
揭秘前端高手的秘密武器:深度解析递归组件与动态组件的奥妙,让你代码效率翻倍!
【10月更文挑战第23天】在Web开发中,组件化已成为主流。本文深入探讨了递归组件与动态组件的概念、应用及实现方式。递归组件通过在组件内部调用自身,适用于处理层级结构数据,如菜单和树形控件。动态组件则根据数据变化动态切换组件显示,适用于不同业务逻辑下的组件展示。通过示例,展示了这两种组件的实现方法及其在实际开发中的应用价值。
40 1
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
76 2
|
2月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
78 0
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
64 0

推荐镜像

更多