【Vue框架】用户和请求
前言
在上一篇 【Vue框架】Vuex状态管理 针对Vuex状态管理以getters.js进行说明,没有对其中state引入的对象进行详细介绍,因为整体都比较简单,也就不对全部做详细介绍了;但其中的user.js涉及到获取用户的信息、前后端请求的token和cookies,因此,这里专门以modules\user.js为头,找到它相关的内容,在从下往上看。
✨该内容个人感觉有点小绕,先整理出了需要看的文件,以及它们间提供方法的关系:
1、utils\auth.js✨
import Cookies from 'js-cookie'
是node_modules里面的方法,这里就不做深入的研究了。
import Cookies from 'js-cookie'// 用于存储表示用户令牌的键名,cookies中携带token用的key
const TokenKey = 'Admin-Token'✨✨// 用于从浏览器的 Cookie 中获取用户令牌
export function getToken() {// 以获取浏览器 Cookie 中 `TokenKey` 对应的值return Cookies.get(TokenKey)
}// 用于将用户令牌存储到浏览器的 Cookie 中
export function setToken(token) {return Cookies.set(TokenKey, token)
}// 用于从浏览器的 Cookie 中移除用户令牌
export function removeToken() {return Cookies.remove(TokenKey)
}
const TokenKey = 'Admin-Token'
就是定义了 前端 向 后端 请求时,请求头中cookie存放token的key。
2、utils\request.js
// 该库用于发送 HTTP 请求
import axios from 'axios'
// 从 `element-ui` 模块中导入了 `MessageBox` 和 `Message`,用于显示弹窗和消息提示
import { MessageBox, Message } from 'element-ui'
// 用于获取应用程序的状态
import store from '@/store'
// 用于获取用户令牌
import { getToken } from '@/utils/auth'// create an axios instance 用于发送 HTTP 请求
const service = axios.create({baseURL: process.env.VUE_APP_BASE_API, // 实际HTTP url = base url + 访问后端的接口request urlwithCredentials: true, // send cookies when cross-domain requests 以在跨域请求时发送跨域请求的源信息,包括 Cookiestimeout: 5000 // request timeout
})// 通过自定义请求拦截器,可以在每个请求发送前对请求进行一些全局配置或处理。在这里,它用于往请求头中添加认证所需的令牌信息
// request interceptor 通过 `service` 实例的 `interceptors.request` 属性调用了 `use` 方法,添加了请求拦截器。
service.interceptors.request.use(config => {// do something before request is sent 请求发送前的操作// 如果存在 `token`,则将 `token` 添加到请求的自定义请求头中if (store.getters.token) {// let each request carry token 让每个请求携带令牌// ['X-Token'] is a custom headers key 指定了自定义请求头的名称为 `X-Token`// please modify it according to the actual situation// 这个步骤确保每个请求在发送前都携带了认证所需的令牌信息config.headers['X-Token'] = getToken()✨✨}return config},// 如果请求拦截器中发生了错误,可以通过错误回调函数捕获并处理error => {// do something with request error// 在这里的错误回调函数中,打印错误信息到控制台console.log(error) // for debug// 以 `Promise.reject(error)` 的形式将错误传递给下一个捕获错误的处理函数return Promise.reject(error)}
)// response interceptor
service.interceptors.response.use(/*** If you want to get http information such as headers or status* Please return response => response*//*** Determine the request status by custom code 通过自定义代码确定请求状态* Here is just an example* You can also judge the status by HTTP Status Code 您也可以通过HTTP状态代码来判断状态* 响应对象response作为参数,该对象包含了响应的信息、状态码等*/response => {const res = response.data// if the custom code is not 20000, it is judged as an error.if (res.code !== 20000) {// 在界面上显示一条消息提示框,`Message` 组件是在全局注册的,所以可以在代码中直接使用Message({message: res.message || 'Error',type: 'error',duration: 5 * 1000 // 消息提示框显示的持续时间为 5 秒(以毫秒为单位)})// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;if (res.code === 50008 || res.code === 50012 || res.code === 50014) {// to re-loginMessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {confirmButtonText: 'Re-Login',cancelButtonText: 'Cancel',type: 'warning'}).then(() => {// 通过调用 `store` 对象的 `dispatch` 方法来触发 `user` 模块中 `actions` 方法的 `resetToken` 动作store.dispatch('user/resetToken').then(() => {location.reload() // 刷新当前页面,以重新加载应用程序})})}return Promise.reject(new Error(res.message || 'Error'))} else {return res}},error => {console.log('err' + error) // for debugMessage({message: error.message,type: 'error',duration: 5 * 1000})return Promise.reject(error)}
)// 将service对象作为默认导出
export default service
2.1 baseURL: process.env.VUE_APP_BASE_API
process.env.VUE_APP_BASE_API 是一个使用了 Vue CLI 创建的 Vue 项目中的环境变量。
在 Vue CLI 中,我们可以在项目根目录下的 .env 文件(或者是以 .env. 开头的文件)中定义环境变量。
具体的配置是在vue.config.js中选择环境,如下图:
baseURL: process.env.VUE_APP_BASE_API
具体的作用:定义一个基本固定的路径,配合后端的接口进行使用。
axios会自动处理基本URL与请求路径的拼接(前端调用的时候,一般是baseURL拼接剩下需要的接口内容)
【下面的例子是,baseURL+完整的api】
eg1. 如果baseURL定义为/abc,后端接口的url应该定义为/user,实际HTTP url是ip/abc/user
eg2. 如果baseURL定义为/abc,后端接口的url应该定义为/abc/user,实际HTTP url是ip/abc/user
eg3. 如果baseURL定义为/abc123,后端接口的url应该定义为/abc/user,实际HTTP url是ip/abc123/abc/user
2.2 为什么这里需要引入store来判断token是否存在?
个人理解:
其实直接使用getToken()的方式也可以的,没有太大的区别,因为本来store.getter中存的token也就是调用getToken()获得的。
2.3 config.headers[‘X-Token’] = getToken()
这里的'X-Token'
其实就是shiro中的Authorization
字段,负责传递token,携带在请求头中。
不像utils\auth.js的const TokenKey = 'Admin-Token'
是存在cookie中,然后cookie在请求头中。
2.4 export default service
这里虽然导出的是service
,但是在别的地方import时可以从新起名
eg. import request from '@/utils/request'
其中的request
就是指这里的service
,而这个service
其实就是配置过的axios
3、api\user.js
// 看2.3 export default service
import request from '@/utils/request'export function login(data) {// 调用 `request(options)`,其中 `options` 是一个包含请求配置的对象return request({url: '/user/login', // 这里的url需要和后台的接口对应上method: 'post',data})
}export function getInfo(token) {return request({url: '/user/info',method: 'get',params: { token }})
}export function logout() {return request({url: '/user/logout',method: 'post'})
}
request
是axios配置后的请求方法,在api文件夹下,主要存放一系列请求后端的方法。
4、modules\user.js
// 注意:在import中导入{ xxx },这里的xxx就是属性,因为是解构式赋值,不加'{}'的就是对象
// 用于处理用户登录、注销和获取用户信息的逻辑
import { login, logout, getInfo } from '@/api/user'
// 用于处理用户令牌(token)的获取、存储和移除操作
import { getToken, setToken, removeToken } from '@/utils/auth'
// 导入 `router` 对象和 `resetRouter` 函数,用于处理路由相关的操作
import router, { resetRouter } from '@/router'// 定义的状态
const state = {// 使用 `getToken` 函数从本地存储中获取用户令牌,并作为初始值赋给 `token` 属性token: getToken(),// 用于存储用户名name: '',// 用于存储用户头像的 URLavatar: '',// 用于存储用户简介信息introduction: '',// 用于存储用户的角色信息roles: []
}// 用于存储一系列 改变 应用状态的方法
// mutation 的作用是更新 Vuex 中的状态,将 `token` 存储在 Vuex 的状态中,以便其他组件可以访问和使用这个 `token`
const mutations = {SET_TOKEN: (state, token) => {state.token = token},SET_INTRODUCTION: (state, introduction) => {state.introduction = introduction},SET_NAME: (state, name) => {state.name = name},SET_AVATAR: (state, avatar) => {state.avatar = avatar},SET_ROLES: (state, roles) => {state.roles = roles}
}// 用于存储一系列 触发改变 应用状态的方法
const actions = {// user loginlogin({ commit }, userInfo) {// 从 `userInfo` 中解构出用户名和密码const { username, password } = userInforeturn new Promise((resolve, reject) => {login({ username: username.trim(), password: password }).then(response => {const { data } = response// 为什么既要存Vuex又存Cookies?为了页面关闭、刷新或重新加载后,可以从cookies中取出用户的token,确保登录状态commit('SET_TOKEN', data.token) // 将获取的 `data.token` 提交给 Vuex 的 `SET_TOKEN` mutationsetToken(data.token) // 将 `token` 存储在Cookies中resolve()}).catch(error => {reject(error)})})},// get user infogetInfo({ commit, state }) {return new Promise((resolve, reject) => {getInfo(state.token).then(response => {const { data } = responseif (!data) {reject('Verification failed, please Login again.')}const { roles, name, avatar, introduction } = data// roles must be a non-empty arrayif (!roles || roles.length <= 0) {reject('getInfo: roles must be a non-null array!')}commit('SET_ROLES', roles)commit('SET_NAME', name)commit('SET_AVATAR', avatar)commit('SET_INTRODUCTION', introduction)resolve(data)}).catch(error => {reject(error)})})},// user logoutlogout({ commit, state }) {return new Promise((resolve, reject) => {logout(state.token).then(() => {commit('SET_TOKEN', '')commit('SET_ROLES', [])removeToken()resetRouter() // 重置路由resolve()}).catch(error => {reject(error)})})},// remove tokenresetToken({ commit }) {return new Promise(resolve => {commit('SET_TOKEN', '')commit('SET_ROLES', [])removeToken()resolve()})}
}export default {namespaced: true,state,mutations,actions
}
为什么既要存Vuex又存Cookies?
为了页面关闭、刷新或重新加载后,可以从cookies中取出用户的token,确保登录状态
相关文章:

【Vue框架】用户和请求
前言 在上一篇 【Vue框架】Vuex状态管理 针对Vuex状态管理以getters.js进行说明,没有对其中state引入的对象进行详细介绍,因为整体都比较简单,也就不对全部做详细介绍了;但其中的user.js涉及到获取用户的信息、前后端请求的token…...

NGINX组件(rewrite)
一、location匹配的规则和优先级(*) URI:统一资源标识符,是一种字符串标识,用于标识抽象的或者是物理资源;如:文件、图片、视频等 nginx中的URI匹配的是:网址”/“后的路径 如&…...

网页显示摄像头数据的方法---基于web video server
1. 背景: 在ros系统中有发布摄像头的相关驱动rgb数据,需求端需要将rgb数据可以直接在网页上去显示。 问题解决: web_video_server功能包,相关链接: web_video_server - ROS Wiki 2. 下载,安装和编译&a…...

SIFT 算法 | 如何在 Python 中使用 SIFT 进行图像匹配
介绍 人类通过记忆和理解来识别物体、人和图像。你看到某件事的次数越多,你就越容易记住它。此外,每当一个图像在你的脑海中弹出时,它就会将该项目或图像与一堆相关的图像或事物联系起来。如果我告诉你我们可以使用一种称为 SIFT 算法的技术来教机器做同样的事情呢? 尽管…...

K8S系列四:服务管理
写在前面 本文是K8S系列第四篇,主要面向对k8s新手同学。阅读本文需要读者对k8s的基本概念,比如Pod、Deployment、Service、Namespace等基础概念有所了解,尚且不了解的同学推荐先阅读本系列的第一篇文章《K8S系列一:概念入门》[1]…...

冠达管理:融券卖出交易规则?
融券卖出买卖是指投资者在没有实际持有某只股票的情况下,经过借入该股票并卖出来取得赢利的一种股票买卖方式。融券卖出买卖规矩针对不同市场、不同证券公司之间可能会存在一些差异,但基本的规矩包含如下几个方面。 一、融资融券的资历要求 在进行融券卖…...

图像变形之移动最小二乘算法(MLS)
基本原理 基于移动最小二乘的图像变形是通过一组源控制点和目标控制点来控制变形,对于每一个待求变形后位置的点而言,根据预设的形变类型(如仿射变换、相似变换、刚性变换)求解一个最小二乘优化目标函数估计一个局部的坐标变换矩阵…...
搭建一个功能齐全的网站
搭建一个功能齐全的网站,需要准备和掌握的一些关键技术和功能可概括如下: 前端技术: HTML/CSS - 网页内容结构和样式JavaScript - 实现网页交互功能前端框架(Vue、React等) - 更高效开发交互页面响应式设计 - 网站适配移动端 后端技术: 服务器(Linux、Nginx等) - 提供网站访…...
Java-jar和war包的区别
jar包和war包的区别: 1、war是一个web模块,其中需要包括WEB-INF,是可以直接运行的WEB模块;jar一般只是包括一些class文件,在声明了Main_class之后是可以用java命令运行的。 2、war包是做好一个web应用后,通…...

分类预测 | MATLAB实现CNN-BiGRU-Attention多输入分类预测
分类预测 | MATLAB实现CNN-BiGRU-Attention多输入单输出分类预测 目录 分类预测 | MATLAB实现CNN-BiGRU-Attention多输入单输出分类预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 Matlab实现CNN-BiGRU-Attention多特征分类预测,卷积双向门控循环…...

C#小轮子:Visual Studio自动编译Sass文件
文章目录 前言插件安装插件使用compilerconfig.jsonsass输入和css输出(自动生成)默认配置(我不懂就不去动他了) 解决Blazor热重载Bug 前言 我们知道css文件用起来太麻烦,如果样式一多,嵌套起来用css样式就…...

iOS字体像素与磅的对应关系
注意:低于iOS10的系统,显示的字宽和字高比高于iOS10的系统小。 这就是iOS10系统发布时,很多app显示的内容后面出现…,因而出现很多app为了适配iOS10系统而重新发布新版本。 用PS设计的iOS效果图中,字体是以像素&#x…...

阿里云ACP知识点
前言:记录ACP错题 1、在创建阿里云ECS时,每台服务器必须要包含_______用来存储操作系统和核心配置。 系统盘(不是实例,实例是一个虚拟的计算环境,由CPU、内存、系统盘和运行的操作系统组成;ESC实例作为云…...

小视频AI智能分析系统解决方案
2022下半年一个项目,我司研发一个基于接收小视频录像文件和图片进行算法分析抓拍的系统,整理了一下主要思想如下: 采用C开发一个AI识别服务,该服务具有如下功能: 创建各类算法模型服务引擎池,每类池内可加载多个模型…...

简单谈谈 EMP-SSL:自监督对比学习的一种极简主义风
论文链接:https://arxiv.org/pdf/2304.03977.pdf 代码:https://github.com/tsb0601/EMP-SSL 其他学习链接:突破自监督学习效率极限!马毅、LeCun联合发布EMP-SSL:无需花哨trick,30个epoch即可实现SOTA 主要…...

nginx的负载均衡
nginx的负载均衡 文章目录 nginx的负载均衡1.以多台虚拟机作服务器1.1 在不同的虚拟机上安装httpd服务1.2 在不同虚拟机所构建的服务端的默认路径下创建不同标识的文件1.3 使用windows本机的浏览器分别访问3台服务器的地址 2.在新的一台虚拟机上配置nginx实现反向代理以及负载均…...
linux系统服务学习(四)Linux系统下数据同步服务RSYNC
文章目录 Linux系统下数据同步服务RSYNC一、RSYNC概述1、什么是rsyncrsync的好姐妹数据同步过程 2、rsync特点3、rsync与scp的区别 二、RSYNC的使用1、基本语法2、本地文件同步3、远程文件同步思考:4、rsync作为系统服务Linux系统服务的思路: 三、任务解…...

走进 Linux
一、开关机 开机: 开机会启动许多程序。他们在windows叫做“服务”(service),在Linux就叫做“守护进程”(daemon)开机成功后,它会显示一个文本登录界面, 这个界面就是我们经常看到的登录界面,在这个登录界…...
Docker高级——Docker Swarm集群和部署应用
创建 Swarm 集群 初始化管理节点 [rootk8s-master ~]# docker swarm init --advertise-addr 192.168.192.133 Swarm initialized: current node (vy95txqo3pglh478e4qew1h28) is now a manager.To add a worker to this swarm, run the following command:docker swarm join …...
【SA8295P 源码分析】74 - QNX secpol 安全策略文件配置详解 及 secpol.bin 编译过程分析
【SA8295P 源码分析】74 - QNX secpol 安全策略文件配置详解 及 secpol.bin 编译过程分析 一、secpol 的编译流程:编译生成 secpol.bin 打包在 ifs2_la.img 中二、QNX 开启 secpol 功能三、为新进程 创建 新的secpol 安全策略:以 vmm_service 为例四、secpol 配置示例,以 I2…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...