前端路由的两种模式:hash 与 history 深度解读

在现代单页应用(SPA)开发中,前端路由是实现无刷新页面切换的关键。Vue-Router 作为 Vue.js 的官方路由管理器,提供了两种模式:hash 模式history 模式。于很多初学者来说,这两种模式的区别可能只停留在“hash模式有#号,history模式没有”的层面。
默认情况下,Vue-Router 采用 hash 模式,因为它实现简单、兼容性好。然而,随着 HTML5 History API 的普及,history 模式因其更美观的 URL 和更强大的功能,逐渐成为许多项目的首选。

一、hash 模式:#路由

1. 什么是 hash 模式?

hash 模式的 URL 中会包含一个 # 符号,例如 http://www.example.com/#/user/123。这里的 #/user/123 就是 hash 值。hash 的设计初衷是页面内锚点,但当它变化时,浏览器不会向服务器发送请求,因此被前端路由巧妙地用来模拟不同页面的切换。

2. 工作原理

hash 模式的核心是监听浏览器的 hashchange 事件。当 URL 中的 hash 部分发生变化时,该事件会被触发,我们可以在回调中获取当前的 hash 值,并动态渲染对应的组件。下面是一个简化的实现:

window.addEventListener('hashchange',()=>{const hash = location.hash.slice(1);// 去掉 # 号// 根据 hash 加载对应视图renderComponent(hash);});// 初始化时也需要处理 window.addEventListener('load',()=>{const hash = location.hash.slice(1)||'home';renderComponent(hash);});

此外,hash 变化会被浏览器记录到历史栈中,因此用户可以使用前进/后退按钮导航,这完全由浏览器原生支持。

3. 特点与适用场景

hash 模式最大的优点是 无需后端配合。因为 hash 部分永远不会被发送到服务器,所以无论用户直接访问还是刷新页面,服务器收到的始终是基础 URL(如 http://www.example.com),返回的永远是同一个入口文件。这使得它非常适合部署在静态文件托管服务(如 GitHub Pages)上,或者在后端配置受限的环境中使用。

然而,它的缺点也显而易见:

  • URL 不够美观# 的存在让链接看起来有些“另类”。
  • 不利于 SEO:搜索引擎通常不会抓取 # 之后的内容,尽管现代搜索引擎有所改进,但依然不如普通路径友好。
  • 数据传递受限:只能通过 hash 字符串传递简单的参数,无法附加复杂的状态数据。

因此,hash 模式特别适合内部使用的后台管理系统、原型演示项目,或需要兼容 IE8 以下浏览器的老旧项目。


二、history 模式:借助 HTML5 History API 的“真”URL

1. 什么是 history 模式?

history 模式利用 HTML5 新增的 History API,让 URL 看起来和普通多页应用完全一样,没有 # 号。例如 http://www.example.com/user/123,这种格式更符合用户的直觉。

2. 工作原理

History API 提供了 pushState()replaceState() 方法,它们可以修改浏览器的历史记录栈,同时改变地址栏的 URL,但不会触发页面刷新。配合 popstate 事件,我们就能在用户点击前进/后退时更新视图。

一个简单的实现如下:

// 切换到 /user/123 并添加历史记录 history.pushState({userId:123},null,'/user/123');// 监听 popstate 事件(仅当用户点击前进/后退时触发) window.addEventListener('popstate',(event)=>{// event.state 中包含了 pushState 设置的 state 对象renderComponent(location.pathname, event.state);});

注意,pushState() 本身不会触发 popstate 事件,所以代码切换路由时需要手动调用渲染函数。

3. 特点与后端配置的必要性

history 模式的 URL 是真实的路径,因此当用户直接访问 http://www.example.com/user/123 或刷新页面时,浏览器会向服务器请求这个路径。如果服务器上没有对应的资源,就会返回 404。为了解决这个问题,必须对后端进行配置:将所有未匹配到静态文件的请求都指向同一个入口文件(通常是 index.html),由前端路由接管路径解析。例如,在 Nginx 中可以这样配置:

location / { try_files $uri $uri/ /index.html; } 

这样的配置意味着服务器始终返回 index.html,然后前端代码根据当前路径渲染对应的组件。

4. 优势与局限

与 hash 模式相比,history 模式的优势非常突出:

  • URL 简洁美观:没有 #,更符合标准 URL 的规范。
  • 可传递复杂状态pushState()state 参数可以携带任意 JavaScript 对象,方便在页面间传递数据。
  • 支持相同 URL 记录:可以多次将同一个 URL 加入历史栈(例如用户多次点击同一个链接),而 hash 模式要求 hash 值必须不同才会新增记录。
  • 可利用 title 属性:虽然目前大多数浏览器忽略 title 参数,但为未来优化留出了空间。

它的局限性主要在于:

  • 需要服务器配合:如果后端没有正确配置,刷新或直接访问就会导致 404。
  • 兼容性略低:IE9 及以下不支持 History API,但现代项目中这已不成问题。
  • 实现相对复杂:但 Vue-Router 等库已经完美封装,开发者几乎感受不到差异。

三、两种模式的深度对比

为了更清晰地理解它们的差异,我们可以从几个关键维度进行对比:

维度hash 模式history 模式
URL 格式包含 #,如 /#/user普通路径,如 /user
核心原理监听 hashchange 事件使用 pushState/replaceState 并监听 popstate
后端依赖完全不需要必须配置回退路由,否则刷新会 404
刷新行为只发送 # 前的部分,不会 404发送完整路径,若无配置则 404
浏览器支持IE8+IE10+
数据传递能力只能通过 hash 字符串传参可通过 state 传递任意数据
SEO 友好性较差相对较好(但 SPA 仍需 SSR)
典型适用场景兼容旧浏览器、无后端配置权限的项目追求美观 URL、已配置好服务器的新项目

除了以上表格,原文章中提到的 pushState() 相对于 hash 的几个优势值得我们再次强调:

  • 同源任意 URLpushState() 可以设置同源下的任何路径,而 hash 只能修改当前文档的片段,灵活性更高。
  • 相同 URL 也记录:即使新 URL 与当前 URL 完全相同,pushState() 也会在历史栈中新增一条记录,这在某些交互场景中非常有用。
  • 可附加状态数据:通过 state 对象,我们可以将页面状态与历史记录绑定,用户在返回时能恢复到之前的状态,而不仅仅是路径。
  • 可设置标题:虽然目前支持有限,但这是未来可能的增强点。

四、如何在项目中做出选择?

在实际开发中,选择哪种模式并没有绝对的对错,而是需要结合项目具体需求来权衡。以下是一些常见的考量因素:

1. 浏览器兼容性要求

如果项目需要支持 IE9 及以下浏览器,那么只能使用 hash 模式。不过,随着微软对旧版 IE 停止支持,大多数现代项目已无需考虑这一点。

2. 后端配置权限

如果你无法控制服务器配置(例如使用 GitHub Pages、某些云存储静态网站托管),hash 模式是更稳妥的选择。GitHub Pages 虽然可以通过配置支持 history 模式,但需要额外的步骤(如使用 404 页面作为 fallback),不如 hash 模式开箱即用。

3. URL 美观需求

如果产品需要对外分享链接,或者对用户体验有较高要求,history 模式的干净 URL 会更受欢迎。例如,电商网站的商品详情页使用 /product/123 显然比 /#/product/123 更专业。

4. SEO 要求

虽然 SPA 的 SEO 本身需要借助服务端渲染(SSR)或预渲染来解决,但 history 模式的 URL 更容易被搜索引擎识别和索引。如果未来计划做 SSR,history 模式也是自然的选择。

5. 功能需求

如果需要在路由切换时携带复杂的状态(如表单数据、滚动位置),history 模式的 state 对象会带来极大便利。而 hash 模式只能靠拼接字符串,不仅麻烦,还有长度限制。

综合来看,对于大多数新项目,尤其是那些有后端配置权限、追求良好用户体验的应用,history 模式是更推荐的选择。而对于简单原型、内部工具或部署环境受限的项目,hash 模式依然是一个简单可靠的备选方案。


五、扩展知识:HTML5 History API 的其他能力

除了 pushStatereplaceState,History API 还提供了以下方法用于控制历史导航:

  • history.back():后退一步,等同于点击浏览器后退按钮。
  • history.forward():前进一步。
  • history.go(n):相对当前页前进或后退 n 步(n 可为负数)。

这些方法都会触发 popstate 事件(除非 n=0),让我们能够统一处理用户导航。

另外,history.length 属性表示当前会话中的历史记录总数,而 history.state 可以获取当前页面的状态对象,方便随时读取。

值得一提的是,pushState()replaceState() 不会触发 popstate 事件,但会更新 history.state。因此,当我们用代码切换路由时,通常需要手动调用渲染函数,并可能结合 history.state 来传递数据。


参考链接:

Read more

Java 开发者如何搞定百度地图 SN 权限签名实践-以搜索2.0接口为例

Java 开发者如何搞定百度地图 SN 权限签名实践-以搜索2.0接口为例

目录 前言 一、SN签名简介 1、SN签名是什么 2、如何开启SN签名 3、SN签名算法 二、在Java中的应用 1、请求Map参数化 2、SN签名生成 3、搜索接口调用 三、APP SN校验失败可能的原因 1、字符编码问题 2、参数顺序 3、timestamp的设置 四、总结 前言         在当今数字化时代,地图服务已成为众多应用程序不可或缺的功能模块。无论是出行导航、位置分享,还是基于地理位置的业务拓展,地图服务都发挥着关键作用。百度地图作为地图服务提供商,为开发者提供了丰富多样的 API 接口,助力各类应用实现强大的地图功能。然而,对于 Java 开发者而言,在使用百度地图 API 时,SN 权限签名这一环节常常成为开发过程中的一个技术难点,

By Ne0inhk
Java 多态

Java 多态

文章目录 * 多态 * 向上转型和向下转型 * 向上转型和重写 * 重写和重载的区别 * 动态绑定和静态绑定 * 用代码来解释什么是多态 * 向下转型 * 多态的优点 * 总结 多态 1. 什么是多态?为什么要使用多态? 简单来说是多种形态,具体来说是去完成某个事情,当不同对象去完成同一件事表现出来的不同结果/状态 打个比方就是同一个人对待不同人表现出来的形态是不同的 2. 多态实现的三个条件: 向上转型和向下转型 向上转型和重写 1. 将子类对象给父类类型的引用 父类类型 对象名 = new 子类类型() 直接赋值的 classAnimal{publicString name;publicint age;publicAnimal(String name,int age){this.name = name;this.age = age;}// 父类中的this是当前对象的引用publicvoideat(){System.out.println(

By Ne0inhk
构建高效AI工作流:Java生态的LangGraph4j框架详解

构建高效AI工作流:Java生态的LangGraph4j框架详解

AI工作流的概念及其在Java生态中的实现框架LangGraph4j 什么是工作流? AI工作流是将多个AI任务、数据处理步骤和业务逻辑按照特定顺序组织起来的自动化流程。有了工作流就不需要让AI来判断是否该执行某个规定的任务。 在Java生态中,AI工作流类似于传统的工作流引擎,但专门为AI任务优化。是将AI能力工程化、工业化的重要手段。通过工作流编排,可以实现: 1. 复杂AI任务的自动化执行 2. 多模型协同工作 3. 与现有业务系统的无缝集成 4. 完整的监控和治理 为什么需要工作流? 在AI应用开发中,我们经常需要串联多个步骤,例如:获取用户输入、调用多个工具、条件判断、循环重试等。传统的方式是将这些步骤写在业务代码中,导致代码冗长、难以维护和扩展。工作流引擎通过将流程可视化、模块化,使得复杂的业务流程变得清晰、易于编排和调试。 传统模式:业务流程分散在各个Service方法中,逻辑耦合 工作流模式:将业务流程抽象为有向图,节点代表操作单元,边控制流程走向 前言 目前比较流行的几种AI工作流平台,像Dify、Coze、阿里云百炼,它们只要通过拖

By Ne0inhk
基于Java+SpringBoot+SSM闲置物品循环交易保障系统(源码+LW+调试文档+讲解等)/闲置物品交易系统/循环交易平台/物品循环利用系统/交易保障机制/闲置物品处理系统/循环交易保障

基于Java+SpringBoot+SSM闲置物品循环交易保障系统(源码+LW+调试文档+讲解等)/闲置物品交易系统/循环交易平台/物品循环利用系统/交易保障机制/闲置物品处理系统/循环交易保障

博主介绍 💗博主介绍:✌全栈领域优质创作者,专注于Java、小程序、Python技术领域和计算机毕业项目实战✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 2025-2026年最新1000个热门Java毕业设计选题大全✅ 2025-2026年最新500个热门微信小程序毕业设计选题大全✅ Java毕业设计最新1000套项目精品实战案例 微信小程序毕业设计最新500套项目精品案例 🌟文末获取源码+数据库🌟 感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人 本文项目技术选型介绍 前端:Spring+SpringMVC+Mybatis 后端:SpringBoot+Mybatis 数据库:MySQL、SQLServer 开发工具:IDEA、Eclipse、Navicat等 ✌关于毕设项目技术实现问题讲解也可以给我留言咨询!!! 详细视频演示 请联系博主获取更详细的演示视频-源码编号4472 具体实现截图 框架介绍 前端技术介绍 SSM 框架在程序设计中具有不可替代的地位。它不仅提供了丰富的功能和强大的性能

By Ne0inhk