路由 (hash模式和history模式)

首先我们了解一下资源请求:

1.什么是资源

在浏览器需要某一个数据或文件进行解析或者浏览器在解析某个脚本的时候需要数据进行DOM渲染等工作,那么这个数据或文件就是浏览器的资源

2.资源怎么获取

浏览器的资源都必须通过资源请求的方式或从缓存中调出的方式进行获取

3.资源请求的过程是什么
  1. 浏览器HTTP的三次握手
  2. 在第三次握手的同时进行通信
  3. 通信就是向某个主机请求资源
    1. 本地的计算机(文件系统)
    2. 本地或远程的服务器(文件系统)
  4. 资源从对象主机响应回客户端(浏览器)
  5. 浏览器对资源进行加载解析

网络请求:
前提:
1. 一定要有一个服务器
2. 文件一定是保存在服务器文件系统的
服务器程序(HTTP服务)

4.下面是我们写的一个服务器文件,通过浏览器可以请求该服务器资源
const express = require('express');
const {resolve} = require('path');const app = express();// 服务器 如果你想通过 http://localhost:8080/home.html
// app.use(express.static(resolve(__dirname, 'public')));// GET  http://localhost:8080/data => {}
// 
app.get('/data', (req, res) => {// application/jsonres.json({name: 'hello lucky',age: 18})
})app.get('/', (req, res) => {// 响应回home.html// res.sendFile()res.sendFile(resolve(__dirname, 'public/home.html'));
});app.get('/list', (req, res) => {// 响应回list.htmlres.sendFile(resolve(__dirname, 'public/list.html'));
})app.listen(8080, () => {console.log('Server is running on PORT 8080');
})

资源目录 home和list资源存放在public文件夹下(普通的html文件)
image.png

以上就是浏览器通过地址访问服务器资源的过程,下面我们继续说下什么是单页面应用,什么是多页面应用

单页面应用/多页面应用

1.单页面应用(spa)

指只有一个页面的web应用,进入页面只需要加载一次相关资源(css、js等),所有内容都包含在此页面中,对每一个功能内容做组件化。单页面应用跳转,就是切换相关组件,仅仅只是刷新局部资源。

2.多页面应用(mpa)

指有多个独立页面的web应用,且进入每个页面都必须重复加载相关资源(js、css等)。多页面应用的跳转,需要整页资源刷新。

3.单页面应用和多页面应用区别?
  1. 页面数量和跳转方式不同。单页面应用通常只有一个主页,而多页面应用包含多个页面。单页面应用通过前端路由实现页面间的切换,仅刷新局部资源;多页面应用在页面跳转时需要整页刷新。
  2. 用户体验和性能不同。单页面应用提供快速流畅的页面切换和局部更新效果,对服务器压力较小,但初次加载时耗时较多;多页面应用有利于搜索引擎优化,每个页面都有自己的独立性,用户体验可能相对较差。
  3. 开发和维护难度不同。单页面应用的开发和维护成本较高,因为它需要处理更多的逻辑和数据;多页面应用虽然易于扩展和数据分析,但每个页面都需要单独设计和实现,维护起来较为复杂。

了解了单页面应用和多页面应用,那么我们知道单页面应用是通过路由控制页面切换,那么路由又有两种形式hashhistory,我们继续了解一下两种形式的工作原理

路由模式(hash/history)

1.hash 模式

hash模式,url如何控制页面切换
使用#来对URL进行截断,#在url中是锚点
#及后面的内容是浏览器端识别的内容
#前面的内容是向服务器请求的URL

下面我们通过代码来理解hash模式是如何工作的

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div id="app"></div><script src="./index.js" type="module"></script>
</body>
</html>
export default function Home () {return `<h1>Home</h1><button id="toListBtn">To List</button>`;
}
import Home from './Home';// 获取根节点下的容器app,也是单页面应用的入口文件
const oApp = document.querySelector('#app');const init = () => {// 监听 hashchange 事件,hash改变后触发window.addEventListener('hashchange', handleRouter, false);handleRouter();bindEvent();
};
// hash 改变后的处理逻辑
function handleRouter () {const hash = window.location.hash.substring(1);switch (hash) {case '/':case '/home':oApp.innerHTML = Home();bindEvent();break;case '/list':oApp.innerHTML = `<h1>List</h1><button id="toHomeBtn">To Home</button>`;bindEvent();break;default:oApp.innerHTML = `<h1>404 Not Found</h1>`;break;     }
}// 页面渲染后,给页面元素添加点击事件
function bindEvent () {const oToListBtn = document.getElementById('toListBtn');const oToHomeBtn = document.getElementById('toHomeBtn');oToListBtn && oToListBtn.addEventListener('click', handleToListBtnClick, false);oToHomeBtn && oToHomeBtn.addEventListener('click', handleToHomeBtnClick, false);
}
// 跳转页面
function handleToListBtnClick () {window.location.hash = '#/list';
}
// 跳转页面
function handleToHomeBtnClick () {window.location.hash = '#/';
}init();
2.history 模式

了解了hash模式之后,history理解起来也比较简单,hash是通过监听hashchange事件来切换不同组件显示,而history则是监听state的改变来切换组件显示,如下代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div id="app"></div>// 请求服务器文件<script src="http://localhost:8080/app.js"></script>
</body>
</html>
const oApp = document.getElementById('app');const init = () => {handleRouter();bindEvent();
}function handleRouter () {const { state } = window.history;console.log(state);switch (state) {case '':case '/':case 'home':case null:    oApp.innerHTML = `<h1>Home</h1><button id="toListBtn">To List</button>`;bindEvent();break;case 'list':oApp.innerHTML = `<h1>List</h1><button id="toHomeBtn">To Home</button>` ;bindEvent();break;default:oApp.innerHTML = `<h1>404 Not Found</h1>`;bindEvent();break;               }
}function bindEvent () {const oToListBtn = document.getElementById('toListBtn');const oToHomeBtn = document.getElementById('toHomeBtn');oToListBtn && oToListBtn.addEventListener('click', handleToListBtnClick, false);oToHomeBtn && oToHomeBtn.addEventListener('click', handleToHomeBtnClick, false);
}function handleToListBtnClick () {window.history.pushState('list', '', '/list');handleRouter();
}function handleToHomeBtnClick () {window.history.pushState('home', '', '/');handleRouter();
}init();
const express = require('express');
const { resolve } = require('path');const app = express();app.use(express.static(resolve(__dirname, 'public')));app.use((req, res) => {res.sendFile(resolve(__dirname, 'public/index.html'));
});app.listen(8080, () => {console.log('Server is running on PORT 8080');
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/285826.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java程序设计】【C00371】基于(JavaWeb)Springboot的社区防疫物资申报系统(有论文)

TOC 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客中有上百套程序可供参考&#xff0c;欢迎共同交流学习。 项目简介 项目获取 &#x1f345;文末点击卡片…

MapReduce配置和Yarn的集群部署

一、集群环境&#xff0c;还是如下三台服务器 192.168.32.101 node1192.168.32.102 node2192.168.32.103 node3 二、YARN架构 YARN&#xff0c;主从架构&#xff0c;有2个角色 主&#xff08;Master&#xff09;角色&#xff1a;ResourceManager从&#xff08;Slave&#x…

政安晨:【深度学习实践】【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(三)—— 随机梯度下降

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 这篇文章中&#xff0c;咱们将使用Keras和TensorFlow…

看似简单的SQL,实则就是简单

加班遇到一个SQL问题&#xff0c;本想把别人的SQL改下成SparkSQL&#xff0c;在YARN上运行&#xff0c;然而数据一直对不上。 原SQL ⚠️说明&#xff1a;a.id&#xff0c;b.id没有空的&#xff0c;数据1:1&#xff0c;b.name可能存在空的 select a.id,b.id,b.name from tab…

JDK1.6、1.7、1.8内存区域的变化?

JDK1.6、1.7/1.8内存区域发生了变化&#xff0c;主要体现在方法区的实现&#xff1a; JDK1.6使用永久代实现方法区&#xff1a; JDK1.7时发生了一些变化&#xff0c;将字符串常量池、静态变量&#xff0c;存放在堆上 在JDK1.8时彻底干掉了永久代&#xff0c;而在直接内存中划出…

【每日八股】Java基础经典面试题4

前言&#xff1a;哈喽大家好&#xff0c;我是黑洞晓威&#xff0c;25届毕业生&#xff0c;正在为即将到来的秋招做准备。本篇将记录学习过程中经常出现的知识点以及自己学习薄弱的地方进行总结&#x1f970;。 本篇文章记录的Java基础面试题&#xff0c;如果你也在复习的话不妨…

阿里的库存秒杀是如何实现的?

一、阿里的库存秒杀的实现 阿里有很多业务&#xff0c;几十上百个业务线&#xff0c;各自都有一些需要做抢购、秒杀、热点扣将的场景。他们都用哪些方案呢? 我看了很多资料&#xff0c;也找了很多人做交流&#xff0c;最终得到的结论是啥都有&#xff0c;主要总结几个主流的&…

Linux离线部署gitLab及使用教程

一、下载gitLab的linux系统rpm包 地址&#xff1a;Index of /gitlab-ce/yum/el7/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 找到这个最新版 点击下载 二、上传到linux系统 笔者是在windows系统下的vmware虚拟机中部署安装的&#xff0c;虚拟机中安装了cent…

《C++ Primer 第五版 中文版》第12章 动态内存【阅读笔记 + 个人思考】

《C Primer 第五版 中文版》第12章 动态内存【阅读笔记 个人思考】 12.1 动态内存与智能指针12.1.1 shared_ptr类 静态内存包括&#xff1a;初始化只读数据段&#xff0c;初始化读写数据段&#xff0c;未初始化数据和常量数据段。 详细在下面博客总结&#xff1a; Linux系统下…

商家如何自己零成本免费制作点餐小程序项目完整源码

现在点餐小程序成为餐饮店的标配&#xff0c;顾客只要扫码&#xff0c;即可进入小程序点餐。顾客付款后&#xff0c;后厨自动打印出订单并开始制作。整个过程非常方便流畅&#xff0c;甚至还可以免去收银&#xff08;或服务&#xff09;人员。那么&#xff0c;这种餐饮小程序要…

STM32—控制蜂鸣器(定时器)

目录 1 、 电路构成及原理图 2 、编写实现代码 main.c tim_irq.c 3、代码讲解 4、烧录到开发板调试、验证代码 5、检验效果 此笔记基于朗峰 STM32F103 系列全集成开发板的记录。 1 、 电路构成及原理图 定时器中断是利用定时器的计数功能&#xff08;向上计数或向下计…

ChatGPTGPT4科研应用、数据分析与机器学习、论文高效写作、AI绘图技术教程

原文链接&#xff1a;ChatGPTGPT4科研应用、数据分析与机器学习、论文高效写作、AI绘图技术教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247598798&idx2&sn014f5ae90306a3b1e8fd87ab58561411&chksmfa820329cdf58a3f72799a43016b223057fd1bd02284…

算法系列--动态规划--子序列(1)

&#x1f495;"深思熟虑的结果往往就是说不清楚。"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;算法系列–动态规划–子序列(2) 今天带来的是算法系列--动态规划--子序列(1),是子序列问题的开篇!带大家初识子序列问题 一.什么是子序列问题 我们…

某蓝队面试经验

背景 据小道消息说今年的国护疑似提前到了五月份&#xff0c;所以最近也是HW面试的一个高峰期啊&#xff0c;这里分享一下上次长亭的蓝队面试问题&#xff08;附本人的回答&#xff0c;仅供参考&#xff09; 面试问答 1、谈谈作为蓝队护网过程使用过厂商的设备 这里我回答的…

Spring Boot整合Spring Security

Spring Boot 专栏&#xff1a;Spring Boot 从零单排 Spring Cloud 专栏&#xff1a;Spring Cloud 从零单排 GitHub&#xff1a;SpringBootDemo Gitee&#xff1a;SpringBootDemo Spring Security是针对Spring项目的安全框架&#xff0c;也是Spring Boot底层安全模块的默认技术…

部署Zabbix Agents添加使能监测服务器_Linux平台_Yum源/Archive多模式

Linux平台 一、从yum源脚本安装部署Zabbix-Agent,添加Linux Servers/PC 概述 Zabbix 主要有以下几个组件组成: Zabbix Server:Zabbix 服务端,Zabbix的核心组件,它负责接收监控数据并触发告警,还负责将监控数据持久化到数据库中。 Zabbix Agent:Zabbix客户端,部署在被监…

Hbase 王者荣耀数据表 HBase常用Shell命令

大数据课本&#xff1a; HBase常用Shell命令 在使用具体的Shell命令操作HBase数据之前&#xff0c;需要首先启动Hadoop&#xff0c;然后再启动HBase&#xff0c;并且启动HBase Shell&#xff0c;进入Shell命令提示符状态&#xff0c;具体命令如下&#xff1a; $ cd /usr/local…

Linux--进程(1)

目录 前言 1.冯诺依曼体系结构 2. 操作系统(Operator System)--第一个被加载的软件 3.进程 3.1基本概念 3.2Linux中的PCB 3.3通过系统调用创建子进程-fork初识 fork&#xff1a;创建一个子进程 为什么要创建子进程&#xff1f; fork的原理&#xff1a; 进一步了解fo…

关于OceanBase中旁路导入的应用分享

背景 前段时间&#xff0c;在用户现场协助进行OceanBase的性能测试时&#xff0c;我注意到用户常常需要运用 insert into select 将上亿行的数据插入到一张大宽表里&#xff0c;这样的批量数据插入操作每次都需要耗时半个小时左右。对这一情况&#xff0c;我提议用户尝试采用旁…

【UE5】动画蒙太奇简述

项目资源文末百度网盘自取 动画蒙太奇基本功能 动画蒙太奇&#xff08;Animation Montage&#xff09; 可以将多个 动画序列&#xff08;Animation Sequences&#xff09; 合并为单个资产并通过蓝图播放&#xff0c;还可以将一个蒙太奇动画切分为多个 蒙太奇分段&#xff08;M…