前端面试问题(jwt/布局/vue数组下标/扁平化/菜单树形/url api/新版本)
前端面试问题(jwt/布局/vue数组下标/扁平化/菜单树形/url api/新版本)
1. jwt鉴权逻辑
前端 JWT 鉴权逻辑通常涉及在发起请求时携带 JWT,并在接收到响应后处理可能的授权问题。
1. 用户登录:
-
用户提供凭证: 用户在登录界面输入用户名和密码。
-
请求后端认证: 前端通过发送用户提供的凭证(通常是用户名和密码)到后端进行身份验证。
-
接收并存储Token: 如果身份验证成功,后端生成 JWT 并将其发送给前端。前端通常会将 JWT 存储在客户端(通常是浏览器)的本地存储(localStorage 或 sessionStorage)中。
2. 请求时的鉴权:
-
构建请求头: 在每次发送请求时,前端将存储的 JWT 添加到请求头中。
// 使用 Axios 发送请求的方式 const token = localStorage.getItem('jwtToken'); axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
-
发送请求: 发送请求到后端,后端会检查请求头中的 JWT 是否有效。
-
处理响应: 前端接收到响应后,可以根据响应状态码和内容进行相应的处理。
-
如果响应状态码为 401(未授权)或 403(禁止访问),可能表示 JWT 已过期或用户无权限,需要处理重新登录或其他操作。
-
如果响应状态码为 200,表示请求成功,前端可以继续处理返回的数据。
-
3. 处理过期的Token:
-
捕获过期错误: 前端需要捕获过期错误。当后端返回 401 状态码时,可以视为 JWT 过期。
-
刷新Token: 如果服务器支持,可以尝试使用 refresh token 来获取新的 JWT,避免用户重新登录。
注意事项:
-
安全存储: JWT 存储在前端,因此需要确保它被安全地存储。一般来说,避免将敏感信息存储在 JWT 中,因为它可以被解码。
-
定期刷新: 定期检查 JWT 是否过期,如果过期,需要进行刷新操作。
-
前端安全性: 前端只能负责存储和传递 JWT,实际的用户身份验证和授权逻辑仍然应该由后端负责。
2. 实现顶部导航+左侧菜单+右侧主内容区域布局
在前端,实现顶部导航、左侧菜单、右侧主内容区域布局通常有多种方式,取决于项目的需求和开发者的技术偏好。以下是其中三种常见的实现方式:
1. Flexbox 布局:
使用 CSS 的 Flexbox 布局是一种简单而灵活的方法,它能够轻松地实现顶部导航、左侧菜单和右侧主内容区域的布局。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Flexbox Layout</title><style>body {margin: 0;display: flex;flex-direction: column;height: 100vh;}header, main {flex: 0 0 auto;}main {display: flex;}nav {width: 200px;background-color: #333;color: #fff;}section {flex: 1;padding: 20px;}</style>
</head>
<body><header><!-- 顶部导航 --><h1>顶部</h1></header><main><nav><!-- 左侧菜单 --><h1>左侧</h1></nav><section><!-- 右侧主内容区域 --><h1>右侧</h1></section></main>
</body>
</html>
2. Grid 布局:
CSS Grid 布局也是一种强大的布局方式,允许更复杂的网格结构。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Grid Layout</title><style>body {margin: 0;display: grid;grid-template-columns: 200px 1fr;grid-template-rows: auto 1fr;grid-template-areas:"header header""nav main";height: 100vh;}header, nav, main {padding: 20px;}header {grid-area: header;background-color: #ddd;}nav {grid-area: nav;background-color: #333;color: #fff;}main {grid-area: main;display: flex;}</style>
</head>
<body><header><!-- 顶部导航 --><h1>顶部</h1></header><nav><!-- 左侧菜单 --><h1>左侧</h1></nav><main><!-- 右侧主内容区域 --><h1>右侧</h1></main>
</body>
</html>
3. Bootstrap:
使用 Bootstrap 框架是一种快速搭建响应式布局的方法。Bootstrap 提供了许多现成的组件和样式,使得实现这种布局变得非常容易。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"><title>Bootstrap Layout</title>
</head>
<body><header class="bg-light p-3"><!-- 顶部导航 --><h1>顶部</h1></header><div class="container-fluid"><div class="row"><nav class="col-md-2 bg-dark text-light"><!-- 左侧菜单 --><h1>左侧</h1></nav><main class="col-md-10"><!-- 右侧主内容区域 --><h1>右侧</h1></main></div></div>
</body>
</html>
4. CSS Float 布局
使用float
属性可以实现一种简单的布局,但需要注意清除浮动以避免影响后续布局。
<div class="header">顶部导航</div>
<div class="menu">左侧菜单</div>
<div class="content">右侧主内容区域</div><style>.header { clear: both; }.menu { float: left; width: 20%; }.content { margin-left: 20%; }
</style>
3. Vue数组下标改值时响应式丢失,为什么
在Vue中,数组下标改值导致响应式丢失的原因通常是由于Vue对数组的监听机制的限制。Vue的响应式系统对于数组的变更检测有一些局限性,主要涉及到以下情况:
-
直接通过索引设置数组元素时,无法触发视图更新: Vue的响应式系统不能检测到直接通过索引设置数组元素的变化。例如,
array[index] = value
这种方式不会触发响应式更新。 -
通过
splice
方法添加或删除元素时能够触发更新: 使用Vue提供的数组变异方法(例如splice
)来添加或删除元素时,Vue能够监听到变化并触发相应的更新。
// 在Vue组件中的data
data() {return {myArray: [1, 2, 3]};
},
methods: {updateValue() {// 这种方式修改数组的元素,不会触发响应式更新this.myArray[0] = 99;}
}
直接通过索引修改数组元素的值 this.myArray[0] = 99;
不会触发Vue的响应式系统。
为了确保能够触发响应式更新,可以使用Vue提供的变异方法,比如使用Vue.set
方法:
methods: {updateValue() {// 使用 Vue.set 来确保触发响应式更新Vue.set(this.myArray, 0, 99);}
}
或者使用splice
方法:
methods: {updateValue() {// 使用 splice 来确保触发响应式更新this.myArray.splice(0, 1, 99);}
}
4. 数组扁平化
-
使用递归(原生 JavaScript):
function flattenArray(arr) {return arr.reduce((acc, curr) => Array.isArray(curr) ? acc.concat(flattenArray(curr)) : acc.concat(curr), []); }const nestedArray = [[0, 1], [2, [3, 4]], [5, 6]]; const flattenedArray = flattenArray(nestedArray); console.log(flattenedArray);
-
使用
Array.flat()
方法(ECMAScript 2019):const nestedArray = [[0, 1], [2, [3, 4]], [5, 6]]; const flattenedArray = nestedArray.flat(Infinity); console.log(flattenedArray);
-
使用 lodash 库:
const _ = require('lodash');const nestedArray = [[0, 1], [2, [3, 4]], [5, 6]]; const flattenedArray = _.flattenDeep(nestedArray); console.log(flattenedArray);
Array.flat()
方法和 lodash 的 _.flattenDeep()
都可以递归地将数组扁平化,而原生的递归方法Array.reduce()` 方法需要手动处理递归。
5. 菜单数组转换为嵌套树形结构
[{ id: 1, menu: '水果', level: 1 }, { id: 2, menu: '橘子', level: 2, parentId: 1 } ]
[{ id: 1, menu: '水果', level: 1, children: [{ id: 2, menu: '橘子', level: 2, parentId: 1 }] }]
function convertToNestedTree(menuArray) {const idToMenuMap = {}; // 用于存储菜单项的映射,通过id快速查找// 构建映射menuArray.forEach(item => {idToMenuMap[item.id] = item;});// 构建树形结构const tree = [];menuArray.forEach(item => {if (!item.parentId) {// 如果没有parentId,说明是根节点,直接添加到树中tree.push(item);} else {// 如果有parentId,将当前项添加到父级的children数组中const parentMenu = idToMenuMap[item.parentId];if (parentMenu) {if (!parentMenu.children) {parentMenu.children = [];}parentMenu.children.push(item);}}});return tree;
}const menuArray = [{ id: 1, menu: '水果', level: 1 },{ id: 2, menu: '橘子', level: 2, parentId: 1 },];const nestedTree = convertToNestedTree(menuArray);
console.log(nestedTree);//[{ id: 1, menu: '水果', level: 1, children: [{ id: 2, menu: '橘子', level: 2, parentId: 1 }] }]
6. url 参数获取的 API
在前端,使用 URLSearchParams
对象来获取 URL 参数。这是一个原生 JavaScript 对象,可用于解析 URL 查询参数。
// 假设 URL 为 https://example.com/page?name=John&age=25const urlParams = new URLSearchParams(window.location.search);// 获取单个参数
const name = urlParams.get('name'); // 返回 'xx'
const age = urlParams.get('age'); // 返回 '25'// 获取所有参数
const allParams = {};
urlParams.forEach((value, key) => {allParams[key] = value;
});console.log(allParams);
// 输出:{ name: 'xx', age: '25' }
使用 URLSearchParams
对象从当前页面的 URL 中提取参数。
7. 新版本发布后,怎么用技术手段通知用户刷新页面
在前端中,可以使用以下几种技术手段来通知用户刷新页面以加载新版本:
-
Service Worker 和 Cache 更新:
- 使用 Service Worker 来缓存资源并控制页面加载。
- 当新版本发布时,Service Worker 可以检测到更新,然后发送消息到页面,通知用户有新版本可用。
- 页面收到消息后,可以显示一个通知或提示,引导用户刷新页面。
-
WebSocket 或 Server-Sent Events (SSE):
- 使用 WebSocket 或 SSE 与服务器建立实时通信通道。
- 当新版本发布时,服务器通过通道向客户端发送消息。
- 客户端收到消息后,可以显示通知并提示用户刷新页面。
-
Polling:
- 定期向服务器发起请求检查是否有新版本。
- 当服务器检测到新版本时,返回相应的信息。
- 页面收到信息后,显示通知并引导用户刷新页面。
-
LocalStorage 或 IndexedDB 标记:
- 在本地存储(LocalStorage)或 IndexedDB 中保存一个标记,表示当前页面的版本。
- 当新版本发布时,将新版本的标记写入本地存储或 IndexedDB。
- 页面加载时检查标记,如果检测到新版本,显示通知并引导用户刷新页面。
-
使用 Service Worker 的
skipWaiting
和clients.claim
:- 在 Service Worker 中使用
self.skipWaiting()
和clients.claim()
来立即激活新版本的 Service Worker。 - 在新版本的 Service Worker 中发送消息到页面,通知用户有新版本可用。
- 页面接收到消息后,显示通知并引导用户刷新页面。
- 在 Service Worker 中使用
相关文章:
前端面试问题(jwt/布局/vue数组下标/扁平化/菜单树形/url api/新版本)
前端面试问题(jwt/布局/vue数组下标/扁平化/菜单树形/url api/新版本) 1. jwt鉴权逻辑 前端 JWT 鉴权逻辑通常涉及在发起请求时携带 JWT,并在接收到响应后处理可能的授权问题。 1. 用户登录: 用户提供凭证: 用户在登录界面输入用户名和密码…...

Learn HTML in 1 hour
website address https://www.youtube.com/watch?vHD13eq_Pmp8 excerpt All right, what’s going on? everybody. It’s your Bro, hope you’re doing well, and in this video I’m going to help you started with html; so sit back, relax and enjoy the show. If y…...

HashMap的put方法执行过程
根据Key通过哈希算法与与运算得出数组下标如果数组下标位置元素为空,则将key和value封装为Entry对象(JDK1.7中是Entry对象,JDK1.8中 是Node对象)并放⼊该位置如果数组下标位置元素不为空,则要分情况讨论 a. 如果是JDK1…...

一、直方图相关学习
目录 1、灰度直方图1.1 基本概念和作用1.2 代码示例 2、BGR直方图2.1 基本概念和作用2.2 代码示例 3、灰度直方图均衡1. 基本概念和作用2. 代码示例 4、直方图变换(查找)4.1 基本概念和作用4.2 代码示例 5、直方图匹配5.1 基本概念和作用5.2 代码示例 6、…...

Linux 权限详解
目录 一、权限的概念 二、权限管理 三、文件访问权限的相关设置方法 3.1chmod 3.2chmod ax /home/abc.txt 一、权限的概念 Linux 下有两种用户:超级用户( root )、普通用户。 超级用户:可以再linux系统下做任何事情ÿ…...

零基础学习8051单片机(十五)
本次先看书学习,并完成了课后习题,题目出自《单片机原理与接口技术》第五版—李清朝 答: (1)当 CPU正在处理某件事情的时候,外部发生的某一件事件请求 CPU 迅速去处理,于是,CPU暂时中止当前的工…...
项目的一些难点
1.不用redis?分布式锁,如何防止用户重复点击? 1.乐观锁 乐观锁是一种在数据库层面上避免并发冲突的机制。它通常通过在数据库记录中添加一个版本号(或时间戳)来实现。每次更新记录时,都会检查版本号是否与数据库中的…...

Kubernetes 卷存储 NFS | nfs搭建配置 原理介绍 nfs作为存储卷使用
1、NFS介绍 NFS(Network File System)是一种分布式文件系统协议,允许客户端远程访问服务器上的文件,实现数据共享。它整合多个存储设备为统一文件系统,方便数据存储和管理,支持负载均衡和故障转移…...

开启智能互动新纪元——ChatGPT提示词工程的引领力
目录 提示词工程的引领力 高效利用ChatGPT提示词方法 提示词工程的引领力 近年来,随着人工智能技术的迅猛发展,ChatGPT提示词工程正逐渐崭露头角,为智能互动注入了新的活力。这一技术的引入,使得人机交流更加流畅、贴近用户需求&…...

ElasticSearch语法
Elasticsearch 概念 入门学习: Index索引>MySQL 里的表(table)建表、增删改查(查询需要花费的学习时间最多)用客户端去调用 ElasticSearch(3 种)语法:SQL、代码的方法(4 种语法) ES 相比于 MySQL,能够自动帮我们做分词,能够非常高效、灵活地查询内…...

SMT贴片加工厂需要哪些加工资料
SMT贴片加工中在评估报价的时候需要给到SMT贴片加工厂以下资料,以便工程师和采购进行工艺和报价评估。 在SMT加工中如果需要供应商提供一站式的加工服务,那么在前期就需要更频繁的沟通和配合,包工包料服务是需要PCB制板资料和制板说明、BOM清…...

jmeter下载base64加密版pdf文件
一、何为base64加密版pdf文件 如下图所示,接口jmeter执行后,返回一串包含大小写英文字母、数字、、/、的长字符串,直接另存为pdf文件后,文件有大小,但是打不开;另存为doc文件后,打开可以看到和…...

【regex】正则表达式
集合 [0-9.] [0-9.\-] 例子 正则表达式,按照规则写,写的时候应该不算困难,但是可读性差 不同语言中regex会有微小的差异 vim 需要转义, perl/python中不需要转义 锚位 \b am\b i am 命名 / 命名捕获组 ( 捕获组(…...
78.Spring和SpringBoot的关系和区别?
一、Spring和SpringBoot的关系和区别 SpringBoot是Spring生态的产品。 Spring Framework是一个容器框架 SpringBoot 它不是一个框架、它是一个可以快速构建基于Spring的脚手架(里面包含了Spring和各种框架),为开发Spring生态其他框架铺平道路࿰…...

【PyTorch][chapter 17][李宏毅深度学习]【无监督学习][ Auto-encoder]
前言: 本篇重点介绍AE(Auto-Encoder) 自编码器。这是深度学习的一个核心模型. 自编码网络是一种基于无监督学习方法的生成类模型,自编码最大特征输出等于输入 Yann LeCun&Bengio, Hinton 对无监督学习的看法. 目录: AE 模型原…...

Modern C++ std::variant的实现原理
前言 std::variant是C17标准库引入的一种类型,用于安全地存储和访问多种类型中的一种。它类似于C语言中的联合体(union),但功能更为强大。与联合体相比,std::variant具有类型安全性,可以判断当前存储的实际…...

⭐北邮复试刷题LCR 018. 验证回文串__双指针 (力扣119经典题变种挑战)
LCR 018. 验证回文串 给定一个字符串 s ,验证 s 是否是 回文串 ,只考虑字母和数字字符,可以忽略字母的大小写。 本题中,将空字符串定义为有效的 回文串 。 示例 1: 输入: s “A man, a plan, a canal: Panama” 输出: true 解释…...
C++面试:数据库的权限管理数据库的集群和高可用
目录 一、数据库的权限管理 1. 用户和角色管理 用户管理 实例举例(以MySQL为例): 角色管理 实例举例(以MySQL为例): 总结 2. 权限和授权 用户和角色管理 用户管理 角色管理 权限和授权 权限 授…...
个人搭建部署gpt站点
2024搭建部署gpt 参照博客 https://cloud.tencent.com/developer/article/2266669?areaSource102001.19&traceIdRmFvGjZ9BeaIaFEezqQBj博客核心点 准备好你的 OpenAI API Key; 点击右侧按钮开始部署: Deploy with Vercel,直接使用 Github 账号登…...
samber/lo 库的使用方法: condition
samber/lo 库的使用方法: condition samber/lo 是一个 Go 语言库,使用泛型实现了一些常用的操作函数,如 Filter、Map 和 FilterMap。汇总目录页面 这个库函数太多,因此我决定按照功能分别介绍,本文介绍的是 samber/l…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...
Linux安全加固:从攻防视角构建系统免疫
Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...
大数据治理的常见方式
大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法,以下是几种常见的治理方式: 1. 数据质量管理 核心方法: 数据校验:建立数据校验规则(格式、范围、一致性等)数据清洗&…...

【java面试】微服务篇
【java面试】微服务篇 一、总体框架二、Springcloud(一)Springcloud五大组件(二)服务注册和发现1、Eureka2、Nacos (三)负载均衡1、Ribbon负载均衡流程2、Ribbon负载均衡策略3、自定义负载均衡策略4、总结 …...