Vue中网络请求方面的思考(Token、axios封装和拦截)
Merry He 4/13/2023
# 什么是token?
所谓的Token,其实就是服务端生成的一串加密字符串、以作客户端进行请求的一个“令牌”。当用户第一次使用账号密码成功进行登录后,服务器便生成一个Token及Token失效时间并将此返回给客户端,若成功登陆,以后客户端只需在有效时间内带上这个Token前来请求数据即可,无需再次带上用户名和密码。
通常前端拿到后台返回的token后会存储到浏览器缓存当中,在每次发起网络请求都将它添加到请求头headers的Authorization字段里。
存储:
- 存储在localStorage或sessionStorage 中,每次调用接口的时候都把它当成一个字段传给后台;
- 存储在cookie 中,让它自动发送,不过缺点就是不能跨域; ( 注: js-cookie插件 )
接下来就是将token添加到HTTP请求头headers中...
# 什么是Axios?
Axios 是一个基于 Promise 的轻量级HTTP 库, 可以用在浏览器和 node.js 中, 用于发起网络请求;
前端项目中使用Axios时, 通常会对Axios做一些封装, 比如在网络请求前和响应前做些什么, 能在一定程度上减小代码冗余和后期维护;
# Vue中axios请求封装
axios基础配置 :
//request.js
import axios from "axios"
import router from "@/router";
//创建axios实例
let axiosInstance = axios.create({
baseURL:"/",
timeOut:1000*12
})
//添加post请求媒体类型
axiosInstance.defaults.headers.post['Content-Type'] = 'application/json';
请求拦截和响应拦截 :
//请求拦截
axiosInstance.interceptors.request.use(
(config)=>{
//假设登录成功时token存在localStorage中
const token = localStorage.getItem("myToken")
token && (config.headers.Authorization = token)
return config
},
(err)=>{
return Promise.reject(err)
}
)
//响应拦截
axiosInstance.interceptors.response.use(
(response)=>{
// 2xx 范围内的状态码都会触发该函数。
//可通过与后台约定的code字段做相应的提示(例:接口状态码200,返回数据的code字段为401主动跳转登录页)
if(response.data.code === 200){
return response
}else if(response.data.code === 401){
//提示用户'登录过期,请重新登录',跳转登录页
router.replace({
path:"/login"
})
}else if(response.data.code === 403){
//提示用户没有权限
}else if(response.data.code === 404){
//提示网络请求不存在
}
//...
},
(err)=>{
/* 超出 2xx 范围的状态码都会触发该函数(例:如果登录过期,但接口的状态码不是200,是401时,可以在此处
通过判断err.response.status === 401来提示登录过期,具体在response还是err里提示可与后台约定*/)
}
return Promise.reject(error);
}
)
一、暴露axios实例,请求数据 :
//request.js
export default axiosInstance
//统一接口文件server.js
import axiosInstance from "./request.js"
export function DownloadInfoList(params=>{
return axiosInstance({
url:"/info/download/list",
method:"get",
params,//指定使用params传参
responseType:"blob"
})
})
/*在axios中,使用params字段传递的参数会拼接在url上,使用data字段传递的参数会放在请求体body中,即
get请求方式使用params字段传参,post请求使用data字段传参*/
二、上一步也可以不暴露axios实例,用axios实例axiosInstance进一步封装常用的get、post、put、delete请求 :
//get请求
export function Get(url,params,config){
return new Promise((resolve,reject)=>{
axiosInstance.get(url,{ params,...config })
.then(res=>{
resolve(res.data)
})
.catch(err=>{
reject(err)
})
})
}
//post请求
export function Post(url,params,config){
return new Promise((resolve)=>{
axiosInstance.post(url,params,config)
.then(res=>{
resolve(res.data)
})
.catch(err=>{
reject(err)
})
})
}
//put请求
export function Put(url,params,config){
return new Promise((resolve)=>{
axiosInstance.put(url,params,config)
.then(res=>{
resolve(res.data)
})
.catch(err=>{
reject(err)
})
})
}
//delete请求(params和data传参都支持)
export function Get(url,params,config){
return new Promise((resolve,reject)=>{
axiosInstance.get(url,{ params:{...params},...config }) //可以这样指定使用params传参
.then(res=>{
resolve(res.data)
})
.catch(err=>{
reject(err)
})
})
}
使用封装好的Get、Post、Put、Delete请求:
//统一接口文件server.js
import { Get、Post、Put、Delete } from "./request.js"
const DownloadInfoList = (p)=> Get("info/download/list",p,{responseType:"blob"})
//组件内使用
DownloadInfoList({name:"123"}).then(res=>{
//do something
}).catch(err=>{
//do something
})