Vue中使用axios的响应拦截器处理请求失败的情况(处理token过期问题)以及 登录成功跳转回原来页面问题

参考axios官方文档

// 响应拦截器
// Add a response interceptor
request.interceptors.response.use(// 在2xx范围内的任何状态代码都会触发此函数,这里主要用于处理响应数据response => {return response},// 任何超出2xx范围的状态码都会触发此函数,这里主要用于处理响应错误error => {const { status } = error.responseif (status === 401) { // 未授权} else if (status === 403) { // 没有权限} else if (status === 404) { // 资源不存在Toast.fail({message: '请求资源不存在',forbidClick: true})} else if (status >= 500) { // 服务端异常Toast.fail({message: '服务端异常,请稍后重试',forbidClick: true})}// 将未处理的异常往外抛return Promise.reject(error)})

处理 token 过期

token过期后,如果发现存在user和token则发送 刷新token的请求,请求头中携带上refresh_token的值,
请求成功后,把获取到的最新的token设置给vuex容器中的user。
因为每次请求时,请求拦截器会从vuex容器中拿token。
这样即使用户token过期了,也会自动去发送刷新token的请求来获取最新的token,而不需要用户手动去登录!
在这里插入图片描述

/*
* 请求模块
* */
import axios from 'axios'
// 在非组件模块中获取store 必须采用这种方式
import store from '../store/index.js'
import JSONbig from 'json-bigint'
import { Toast } from 'vant'
import router from '../router'const request = axios.create({baseURL: '/api', // 基础路径transformResponse: [function (data) {// Do whatever you want to transform the data// console.log(data)// 后端返回的数据可能不是 JSON 格式字符串// 如果不是的话,那么 JSONbig.parse 调用就会报错// 所以我们使用 try-catch 来捕获异常,处理异常的发生try {// 如果转换成功,则直接把结果返回return JSONbig.parse(data)} catch (err) {console.log('转换失败', err)// 如果转换失败了,则进入这里// 我们在这里把数据原封不动的直接返回给请求使用return data}// axios 默认在内部使用 JSON.parse 来转换处理原始数据// return JSON.parse(data)}]
})const refreshTokenReq = axios.create({baseURL: '/api' // 基础路径
})
// 请求拦截器
request.interceptors.request.use(function (config) {const { user } = store.state// 如果用户已登录,统一给接口设置tokenif (user) {config.headers.Authorization = `Bearer ${user.token}`}// 处理完之后一定要把config 返回,否则请求发不出去return config
}, function (err) {return Promise.reject(err)
})// 响应拦截器
request.interceptors.response.use(function (response) {// 响应成功进入这里return response
}, async function (error) {// 响应失败进入这里const status = error.response.statusif (status === 400) {// 客户端请求参数错误Toast.fail('客户端请求参数错误')} else if (status === 401) {// token无效// 如果没有 user 或者 user.token, 直接去登录const { user } = store.stateif (!user || !user.token) {// 直接跳转到登录页面return redirectLogin()}// 使用refresh_token,则请求获取新的tokentry {const { data } = await refreshTokenReq({method: 'PUT',url: '/app/v1_0/authorizations',headers: {Authorization: `Bearer ${user.refresh_token}`}})// 拿到新的token之后把它更新到容器中user.token = data.data.tokenstore.commit('setUser', user)// 把失败的请求重新发送出去// error.config 是本次请求的相关配置项// 注意: 这里使用request发请求,它会走自己的请求拦截器,它的请求//  拦截器中通过store容器访问token数据return request(error.config)// console.log(data)} catch (err) {// 刷新token都失败了,直接跳转到登录页redirectLogin()}} else if (status === 403) {// 没有权限操作Toast.fail('没有权限操作')} else if (status >= 500) {// 服务端异常Toast.fail('服务端异常,请稍后重试!')}// console.dir(error)return Promise.reject(error)
})function redirectLogin () {router.replace('/login')
}// 导出
export default request

登录成功跳转回原来页面

首先在响应拦截器中:
在这里插入图片描述
注意:
router.currentRoute 和 我们在组件中获取的this.$route是一个东西
在这里插入图片描述
在这里插入图片描述

// 响应拦截器
request.interceptors.response.use(// 响应成功进入第1个函数// 该函数的参数是响应对象function (response) {// Any status code that lie within the range of 2xx cause this function to trigger// Do something with response datareturn response},// 响应失败进入第2个函数,该函数的参数是错误对象async function (error) {// Any status codes that falls outside the range of 2xx cause this function to trigger// Do something with response error// 如果响应码是 401 ,则请求获取新的 token// 响应拦截器中的 error 就是那个响应的错误对象console.dir(error)if (error.response && error.response.status === 401) {// 校验是否有 refresh_tokenconst user = store.state.userif (!user || !user.refresh_token) {// router.push('/login')
+        redirectLogin()// 代码不要往后执行了return}// 如果有refresh_token,则请求获取新的 tokentry {const res = await axios({method: 'PUT',url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations',headers: {Authorization: `Bearer ${user.refresh_token}`}})// 如果获取成功,则把新的 token 更新到容器中console.log('刷新 token  成功', res)store.commit('setUser', {token: res.data.data.token, // 最新获取的可用 tokenrefresh_token: user.refresh_token // 还是原来的 refresh_token})// 把之前失败的用户请求继续发出去// config 是一个对象,其中包含本次失败请求相关的那些配置信息,例如 url、method 都有// return 把 request 的请求结果继续返回给发请求的具体位置return request(error.config)} catch (err) {// 如果获取失败,直接跳转 登录页console.log('请求刷线 token 失败', err)// router.push('/login')
+        redirectLogin()}}return Promise.reject(error)}
)+ function redirectLogin () {
+   // router.currentRoute 当前路由对象,和你在组件中访问的 this.$route 是同一个东西// query 参数的数据格式就是:?key=value&key=value
+   router.push('/login?redirect=' + router.currentRoute.fullPath)
+ }

然后在登录成功以后:

const redirect = this.$route.query.redirect || "/";
this.$router.push(redirect);

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

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

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

相关文章

cocoapods 命令

1.使用CocoaPods a 新建一个项目,名字cocoapods b 终端中,cd到项目总目录(直接拖过来) [objc] copy? cd /Users/pengjian/Desktop/cocoapodsc 建立Podfile(配置文件) 接着上一步,终端输入 v…

Vue项目中使用 路由导航守卫 处理页面的访问权限

参考Vue-Router官方文档 Vue-Router导航守卫 效果展示 1、给需要登录状态才能访问的页面路由对象的 meta 中添加配置属性 { // 小智同学name: user-chat,path: /user/chat,component: () > import(/views/user-chat),meta: { requiresAuth: true } },2、通过路由拦截器…

python的最受欢迎的库_2018年最受欢迎的15个Python库

2018 年最受欢迎的15个顶级 Python 库作者 | Goutham Veeramachaneni近日,数据科学网站 KDnuggets 评选出了顶级 Python 库 Top15,领域横跨数据科学、数据可视化、深度学习和机器学习。如果本文有哪些遗漏,你可以在评论区补充。图 1&#xff…

失败,因为你其实太过傲慢

因为你太过傲慢,不肯放低姿态去向他人学习,勤加练习,所以失败。转载于:https://www.cnblogs.com/panie2015/p/5667464.html

Uniapp学习笔记(数据展示、数据循环、条件编译、计算属性、组件的使用、组件插槽、生命周期)

1.项目准备 1.1开发方式 uni-app为我们提供2种开发方式: 使用DCloud公司提供HBuilderX工具来快速开发; 使用脚手架来快速开发(我们这次项目使用此方式); 1.2脚手架搭建项目 全局安装,如果你以前安装过…

word图片嵌入式为何只能看到一部分_Word排版的正确姿势!(Word论文排版教学)...

Hello,最近正值着手写毕业论文的初期,趁着这个时间点,我做了一个简易的,简单的,0基础的Word论文排版教学,帮助你在撰写论文的时候不再花费大量的时间浪费在调整格式里。初次做视频,难免有错误&a…

云计算三种服务模式SaaS、PaaS和IaaS及其之间关系(顺带CaaS、MaaS)

云计算架构图 很明显,这五者之间主要的区别在于第一个单词,而aaS都是as-a-service(即服务)的意思,这五个模式都是近年来兴起的,且这五者都是云计算的落地产品,所以我们先来了解一下云计算是什么…

python多线程和异步性能对比_python对比线程,进程,携程,异步,哪个快

目录概念介绍测试环境开始测试测试【单进程单线程】测试【多进程 并行】测试【多线程 并发】测试【协程 异步】结果对比绘图展示概念介绍首先简单介绍几个概念:进程和线程进程就是一个程序在一个数据集上的一次动态执行过程(数据集是程序在执行过程中所需要使用的资…

uni-ui介绍uni-api

一、uni-ui介绍 安装 二、uni-api 解决uni-app中的跨域问题: "h5" : {"router" : {"mode" : "hash"},"devServer": {"https": false,"proxy": {"/web": {"target": …

推算生日的故事

小明和小强都是张老师的学生,张老师的生日是某月某日,2人都不知道张老师的生日。 生日是下列10组中一天: 3月4日 3月5日 3月8日 6月4日 6月7日 9月1日 9月5日 12月1日 12月2日 12月8日 张老师把月份告诉了小明,把日子告诉了小强…

ubuntu18.04安装python3_在 Ubuntu 18.04 上安装 Python 3.7

扩展源安装sudo apt updatesudo apt install software-properties-commonsudo add-apt-repository ppa:deadsnakes/ppa# 按回车继续sudo apt install python3.7python3.7 --version#安装pipwget https://bootstrap.pypa.io/get-pip.pypython3.7 get-pip.py#安装python3.7-devel…

一、uniapp项目(封装异步请求、moment.js时间处理、封装手势滑动组件、下载图片到本地)

一、封装异步请求: 1. 为什么要封装? 2. 封装的思路 export default (params) > {// 显示加载中uni.showLoading({title: "加载中"})return new Promise((resolve, reject) > {wx.request({...params,success(res) {resolve(res)},fail…

.net中如何发送HTTP请求网络资源

应用场景 应该说只要是需要通过发送Http请求获取网络资源的地方都要使用它,网络资源可以是指以URI来表示的资源,比如web api接口等。 HttpWebRequest .net2.0 ~ .net4.0使用HttpWebRequest 代码如下: 1 //.net2.0 ~ .net4.0使用HttpWebReque…

python ftplib_python:使用ftplib编写FTP客户端

Python中的ftplib模块Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件FTP的工作流程及基本操作可参考协议RFC959ftp登陆连接from ftplib import FTP #加载ftp模块ftpFTP() #设置变量ftp…

二、uniapp项目(分段器的使用、scroll-view、视频下载、转发)

一、分段器组件的使用 uniapp官方文档 <template><view class"category"><view class"category_tab"> <view class"category_tab_title"><view class"title_inner"><uni-segmented-control :curr…

HTTP 请求头中的 X-Forwarded-For

本文转载自https://imququ.com/post/x-forwarded-for-header-in-http.html 我一直认为&#xff0c;对于从事 Web 前端开发的同学来说&#xff0c;HTTP 协议以及其他常见的网络知识属于必备项。一方面&#xff0c;前端很多工作如 Web 性能优化&#xff0c;大部分规则都跟 HTTP、…

【Bash/Shell】知识总结

文章目录 1. 总体认识1.1. Shell概述1.2. 第一个Shell脚本1.3. 注释 2. 变量2.1. 定义变量2.2. 使用变量2.3. 只读变量2.4. 删除变量2.5. 变量类型2.5.1. 字符串变量2.5.2. 整数变量2.5.3. 数组变量2.5.4. 环境变量2.5.5. 特殊变量 3. 输出3.1. echo命令3.2. printf命令 4. 运算…

problem b: 一年中的第几天_第九届蓝桥杯B组试题

1.标题&#xff1a;第几天2000年的1月1日&#xff0c;是那一年的第1天。那么&#xff0c;2000年的5月4日&#xff0c;是那一年的第几天&#xff1f;注意&#xff1a;需要提交的是一个整数&#xff0c;不要填写任何多余内容。“手动分割”大小月判断&#xff1a;https://jingyan…

一、express 路由 todos案例

一、express路由 动态路由参数 params 路径参数 query 二、 todos案例 2.1 准备工作 新建一个文件夹01-demo执行npm init -y 生成package.json配置文件执行npm install express --save 安装express新建app.js文件&#xff0c;这是程序的入口文件新建db.json文件&#xff0…

Spiral Matrix I II

Spiral Matrix I Given an integer n, generate a square matrix filled with elements from 1 to n^2 in spiral order. Example Given n 3, You should return the following matrix: [[ 1, 2, 3 ],[ 8, 9, 4 ],[ 7, 6, 5 ] ]分析&#xff1a;从上&#xff0c;右&#xff0c…