0

0

什么是前端路由及解释

小云云

小云云

发布时间:2018-02-10 10:19:48

|

4270人浏览过

|

来源于php中文网

原创

什么是前端路由

所谓的前端路由,拥有这样一种能力:客户端浏览器可以不依赖服务端,根据不同的URL渲染不同的视图页面。

前端路由的存在合理性

在Ajax之剑还未亮出,前端仍处于襁褓之中的时候,路由的工作交给了后端。在进行页面切换的时候,浏览器发送不同的<span style="font-size: 14px;">url</span>请求;服务器接收到浏览器的请求时,通过解析不同的<span style="font-size: 14px;">url</span>去拼接需要的<span style="font-size: 14px;">html</span>或者模板,然后将结果返回给浏览器端进行渲染。

服务器端路由也是不落俗套的有利亦有弊。它的好处是安全性更高,更严格得控制页面的展现。这在某些场景中是很有用的,譬如下单支付流程,每一步只有在上一步成功执行之后才能抵达。这在服务器端可以为每一步流程添加验证机制,只有验证通过才返回正确的页面。那么前端路由不能实现每一步的验证?自然不是,姑且相信你的代码可以写的很严谨,保证正常情况下流程不会错,但是另一个不得不面对的事实是:前端是毫无安全性可言的。用户可以肆意修改代码来进入不同的流程,你可能会为此添加不少的处理逻辑。相较之下,当然是后端控制页面的进入权限更为安全和简便。

另一方面,后端路由无疑增加了服务器端的负荷,并且需要<span style="font-size: 14px;">reload</span>页面,用户体验其实不佳。

立即学习前端免费学习笔记(深入)”;

这样,前端路由就有用武之地了。首先,它的出现无疑减轻了服务器端的压力。特别是对于一个比较复杂的应用来讲,或者更确切的说,对于拥有一个复杂路由系统的应用来说,服务器端需要为每一个不同的url执行一段处理逻辑在高并发的情况下实在有点不堪重负;其次,页面的切换可以不需要刷新整个页面了,没有网络延迟,没有闪烁刷新,提升了用户体验。

前端路由实现方式

既然目标实现,我们需要解决的问题有哪些?我们可以将问题拆的稍微细一点,先制定一个亿的小计划,实现之后再进行下一步:)

  • 在页面不刷新的前提下实现<span style="font-size: 14px;">url</span>变化

  • 捕捉到<span style="font-size: 14px;">url</span>的变化,以便执行页面替换逻辑

如何实现更新<span style="font-size: 14px;">url</span>并且页面不刷新

正如前面所说,前端路由相较于后端路由的一个特点就是页面在不完全刷新的情况下进行视图的切换。页面<span style="font-size: 14px;">url</span>变了,但是并没有重新加载!看上去似乎有点不可思议,其实也没什么大不了。

试想将浏览器地址栏当做一个输入框,我们需要实现的就是改变输入框的<span style="font-size: 14px;">value</span>但是不触发请求页面的操作,这样就不会重新加载新页面。倘若输入框的值的变化和发送请求是一个原子操作,我们也就束手无策了。庆幸的是,只有当我们敲击了回车之后,请求才会被发送出去(这是显而易见的吧)。因此这就为我们修改地址栏的值而不触发页面请求刷新创造了条件。BOM是否有提供修改浏览器地址栏<span style="font-size: 14px;">url</span>而不触发请求操作的方法呢?

这里,存在两种满足需求的方式。一是利用<span style="font-size: 14px;">url</span>中的<span style="font-size: 14px;">hash</span>字段;二是使用HTML5提供的history API

<span style="font-size: 14px;">hash</span>方式

了解<span style="font-size: 14px;">http</span>协议就会知道,<span style="font-size: 14px;">url</span>的组成部分有很多,譬如协议、主机名、资源路径、查询字段等等,其中包含一个称之为片段的部分,以<span style="font-size: 14px;">#</span>为标识。

例如: <span style="font-size: 14px;">http://www.gmail.com/text/#123</span><span style="font-size: 14px;">123</span>便是<span style="font-size: 14px;">url</span>中的<span style="font-size: 14px;">hash</span>部分。

打开控制台,输入 <span style="font-size: 14px;">location.hash</span>,你可以得到当前<span style="font-size: 14px;">url</span><span style="font-size: 14px;">hash</span>部分(如果当前<span style="font-size: 14px;">url</span>不存在<span style="font-size: 14px;">hash</span>则返回空字符串)。接下来,输入 <span style="font-size: 14px;">location.hash = '123'</span>,会发现浏览器地址栏的<span style="font-size: 14px;">url</span>变了,末尾增加了<span style="font-size: 14px;">#123</span>字段,并且,页面没有被重新刷新。很显然,这很符合我们的要求。

history API

HTML5引入了一个<span style="font-size: 14px;">history</span>对象,包含了一套访问浏览器历史的API,可以通过<span style="font-size: 14px;">window.history</span>访问到它。

这里我们看上了它的两个API方法:<span style="font-size: 14px;">pushState</span><span style="font-size: 14px;">replaceState</span>

Peppertype.ai
Peppertype.ai

高质量AI内容生成软件,它通过使用机器学习来理解用户的需求。

下载
<span style="font-size: 14px;">history.replaceState(dataObj, title, url);<br/>history.pushState(dataObj, title, url);<br/></span>

若上所示,它们接收完全相同的参数,都是对浏览器的历史栈进行操作,将传递的url和相关数据压栈,并将浏览器地址栏的<span style="font-size: 14px;">url</span>替换成传入的<span style="font-size: 14px;">url</span>且不刷新页面(正中下怀!)。

By the way,不同的地方是pushState 将指定的url直接压入历史记录栈顶,而 replaceState 是将当前历史记录栈顶替换成传入的数据。

这两种方式都可以帮我们满足题设条件。采用哪一种方式除了主观喜好之外,还得依照客观事实:低版本的浏览器对于history API的兼容性不好,例如遇到了IE8,摆在眼前的道路似乎就别无选择了。

如何跟踪<span style="font-size: 14px;">url</span>变化

在浏览器端,跟踪表单属性的变化一般都采用事件监听机制,跟踪<span style="font-size: 14px;">url</span>的变化也不落俗套。

对于<span style="font-size: 14px;">hash</span>方式的前端路由,通常可以监听 <span style="font-size: 14px;">hashchange</span> 事件,在事件回调中处理相应的页面视图展示等逻辑。

此外,HTML5提供的 <span style="font-size: 14px;">popstate</span> 事件也会在<span style="font-size: 14px;">url</span><span style="font-size: 14px;">hash</span>发生改变时触发。也就是说如果可以忽略低版本浏览器,我们使用<span style="font-size: 14px;">hash</span>方式路由时也可以采用监听这个事件进行回调处理。

那么,如果是采用history API的形式呢?根据MDN的描述:

调用 <span style="font-size: 14px;">history.pushState()</span> 或者 <span style="font-size: 14px;">history.replaceState()</span> 不会触发 <span style="font-size: 14px;">popstate</span> 事件。<span style="font-size: 14px;">popstate</span> 事件只会在浏览器某些行为下触发, 比如点击后退按钮(或者在JavaScript中调用 <span style="font-size: 14px;">history.back()</span> 方法)。

这也就是说,我们在使用history API改变浏览器的<span style="font-size: 14px;">url</span>时,仍需要额外的步骤去触发 <span style="font-size: 14px;">popstate</span> 事件,例如调用 <span style="font-size: 14px;">history.back()</span><span style="font-size: 14px;">history.forward()</span> 等方法。

从兼容性上来讲,前面有提及<span style="font-size: 14px;">hash</span>的方式兼容性更好。然而,对于低版本的浏览器,例如IE6等等,不支持 <span style="font-size: 14px;">hashchange</span> 事件。这个时候我们只能通过 <span style="font-size: 14px;">setInterval</span> 设置心跳的方式去模拟 <span style="font-size: 14px;">hashchange</span>

<span style="font-size: 14px;">var oldHash = location.hash;var oldURL = location.href;<br/><br/>setInterval(function() {    var newHash = location.hash;    var newURL = location.href;    if (newHash !== oldHash && typeof window.onhashchange === 'function') {        // 执行onhashchange回调<br/>        window.onhashchange({            'type': 'hashchange',            'oldURL': oldURL,            'newURL': newURL<br/>        });<br/><br/>        oldHash = newHash;<br/>        oldURL = newURL;<br/>    }<br/>}, 100);<br/></span>

一个简单实现

这里,给出一个很简单的实现:

<span style="font-size: 14px;">router.js</span>

<span style="font-size: 14px;">function FrontRouter() {    this.routes = {};<br/>    window.addEventListener('load', this.resolve.bind(this), false);<br/>    window.addEventListener('hashchange', this.resolve.bind(this), false);<br/>}<br/><br/>FrontRouter.prototype.route = function(path, callback) {    this.routes[path] = callback || function() {};<br/>};<br/><br/>FrontRouter.prototype.resolve = function() {    this.curHash = location.hash.slice(1) || '/';    typeof this.routes[this.curHash] === 'function' && this.routes[this.curHash]();<br/>};<br/></span>

<span style="font-size: 14px;">index.html</span>

<span style="font-size: 14px;"><ul>    <li><a href='#blue'></a></li>    <li><a href='#yellow'></a></li>    <li><a href='#red'></a></li></ul><br/></span>

<span style="font-size: 14px;">index.js</span>

<span style="font-size: 14px;">var router = new FrontRouter();<br/><br/>router.route('blue', function() {<br/>    document.body.style.backgroundColor = 'blue';<br/>});<br/><br/>router.route('yellow', function() {<br/>    document.body.style.backgroundColor = 'yellow';<br/>});<br/><br/>router.route('red', function() {<br/>    document.body.style.backgroundColor = 'red';<br/>});<br/></span>

一点总结

应用场景

前端路由大部分的应用场景,就是我们现在熟知的单页应用SPA。

不存在纯前端路由

我们此前所描述的前端路由,建立在已经打开了一个初始页面基础之上,然后在这个页面之内进行页面替换。然而,我们如何进入这个初始页面?仅靠前端路由肯定是力所不及。我们至少要向后端发送一次http请求,接收所需要加载的页面不是吗?

所以,我们并不能抛弃后端路由部分。这也意味着,我们需要和后端确认各自的分工,哪些url归前端解析,哪些归后台解析。

相关文章

路由优化大师
路由优化大师

路由优化大师是一款及简单的路由器设置管理软件,其主要功能是一键设置优化路由、屏广告、防蹭网、路由器全面检测及高级设置等,有需要的小伙伴快来保存下载体验吧!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

127

2026.02.25

Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法
Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法

本专题系统整理Steam官网最新可用入口,涵盖网页版登录地址、新用户注册流程、账号登录方法及官方游戏商店访问说明,帮助新手玩家快速进入Steam平台,完成注册登录并管理个人游戏库。

18

2026.02.25

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

15

2026.02.25

Python数据处理流水线与ETL工程实战
Python数据处理流水线与ETL工程实战

本专题聚焦 Python 在数据工程场景下的实际应用,系统讲解 ETL 流程设计、数据抽取与清洗、批处理与增量处理方案,以及数据质量校验与异常处理机制。通过构建完整的数据处理流水线案例,帮助开发者掌握数据工程中的性能优化思路与工程化规范,为后续数据分析与机器学习提供稳定可靠的数据基础。

1

2026.02.25

Java领域驱动设计(DDD)与复杂业务建模实战
Java领域驱动设计(DDD)与复杂业务建模实战

本专题围绕 Java 在复杂业务系统中的建模与架构设计展开,深入讲解领域驱动设计(DDD)的核心思想与落地实践。内容涵盖领域划分、聚合根设计、限界上下文、领域事件、贫血模型与充血模型对比,并结合实际业务案例,讲解如何在 Spring 体系中实现可演进的领域模型架构,帮助开发者应对复杂业务带来的系统演化挑战。

1

2026.02.25

Golang 生态工具与框架:扩展开发能力
Golang 生态工具与框架:扩展开发能力

《Golang 生态工具与框架》系统梳理 Go 语言在实际工程中的主流工具链与框架选型思路,涵盖 Web 框架、RPC 通信、依赖管理、测试工具、代码生成与项目结构设计等内容。通过真实项目场景解析不同工具的适用边界与组合方式,帮助开发者构建高效、可维护的 Go 工程体系,并提升团队协作与交付效率。

18

2026.02.24

Golang 性能优化专题:提升应用效率
Golang 性能优化专题:提升应用效率

《Golang 性能优化专题》聚焦 Go 应用在高并发与大规模服务中的性能问题,从 profiling、内存分配、Goroutine 调度、GC 机制到 I/O 与锁竞争逐层分析。结合真实案例讲解定位瓶颈的方法与优化策略,帮助开发者建立系统化性能调优思维,在保证代码可维护性的同时显著提升服务吞吐与稳定性。

9

2026.02.24

Golang 面试题精选:高频问题与解答
Golang 面试题精选:高频问题与解答

Golang 面试题精选》系统整理企业常见 Go 技术面试问题,覆盖语言基础、并发模型、内存与调度机制、网络编程、工程实践与性能优化等核心知识点。每道题不仅给出答案,还拆解背后的设计原理与考察思路,帮助读者建立完整知识结构,在面试与实际开发中都能更从容应对复杂问题。

6

2026.02.24

Golang 运行与部署实战:从本地到云端
Golang 运行与部署实战:从本地到云端

《Golang 运行与部署实战》围绕 Go 应用从开发完成到稳定上线的完整流程展开,系统讲解编译构建、环境配置、日志与配置管理、容器化部署以及常见运维问题处理。结合真实项目场景,拆解自动化构建与持续部署思路,帮助开发者建立可靠的发布流程,提升服务稳定性与可维护性。

5

2026.02.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 5.6万人学习

麻省理工大佬Python课程
麻省理工大佬Python课程

共34课时 | 5.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号