封装axios异步请求 封装request.js
异步请求:XMLHttpRequest ,而axios其实就是对它的封装而已。它可以完成服务端数据请求和响应(交互)也俗称接口的调用。
1:下载
npm install axios
yarn add axios
pnpm install axios
2: 使用
const axios = require('axios');
get请求
// 向给定ID的用户发起请求
axios.get('/user?ID=12345')
.then(function (response) {
// 处理成功情况
console.log(response);
})
.catch(function (error) {
// 处理错误情况
console.log(error);
})
.then(function () {
// 总是会执行
});
// 上述请求也可以按以下方式完成(可选)
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.then(function () {
// 总是会执行
});
// 支持async/await用法
async function getUser() {
try {
const response = await axios.get('/user?ID=12345');
console.log(response);
} catch (error) {
console.error(error);
}
}
post请求
// 发起一个post请求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});
请求必须是有认识路径的问题:
// 肯定没问题
const resp = await axios.post("http://45.85.69.125/login/toLogin", loginUser)
// a能 b不能
const resp = await axios.post("/login/toLogin", loginUser)
不论你调用的get/post/delete/put等。第一个参数:都是URL。
什么是URL:统一资源定位符 (一种能够方式能够快速在电脑定位的资源(图片,文件,音频,视频。数据(文本,json,.xml)))
但是URL得组成:协议(tcp/ucp) + ip+port+资源访问路径?参数,锚点-
- ip + port 找你你访问的资源在哪里(在那台电脑上的那个服务)
3:封装思考
// 查询视频信息
const handleLoadData = async () => {
const resp = await axios.post("/video/find",{},{
headers: {'Authorization': userStore.token}
})
console.log('resp', resp)
}
- post/get请求传递header时候位置不一样。能不能像办法规避这个问题
- 能不能自动取拼接
http://localhost:8989/api,这样我上面代码中就直接写想对路径 - header是信息能不能统一管理。
- 请求错误,超时,能不能监听
- 后端返回的状态很多,但是有一些状态是要做集中处理,比如:登录,服务器错误,404错误等等
4:完整封装代码
// 1: 导入axios异步请求组件
import axios from "axios";
// 2: 把axios请求的配置剥离成一个config/index.js的文件
import axiosConfig from "./config";
// 3: 获取路由对象--原因是:在加载的过程中先加载的pinia所以不能useRouter机制。
import router from '@/router'
// 4: elementplus消息框
import KVA from "@/utils/kva.js";
// 5: 获取登录的token信息
import { useUserStore } from '@/stores/user.js'
// 6: 然后创建一个axios的实例
const request = axios.create({ ...axiosConfig })
// request request请求拦截器
request.interceptors.request.use(
function(config){
console.log("config=====>",config)
// 这个判断就是为了那些不需要token接口做开关处理,比如:登录,检测等
if(!config.noToken){
// 如果 token为空,说明没有登录。你就要去登录了
const userStore = useUserStore()
const isLogin = userStore.isLogin
if(!isLogin){
router.push("/login")
return
}else{
// 90b7d374acc5476eb9beabe9373b2640
// 这里给请求头增加参数.request--header,在服务端可以通过request的header可以获取到对应参数
// 比如go: c.GetHeader("Authorization")
// 比如java: request.getHeader("Authorization")
config.headers.Authorization = userStore.getToken()
// 挤下线使用
// config.headers.KsdUUID = userStore.uuid
}
}
return config;
},function(error){
// 判断请求超时
if ( error.code === "ECONNABORTED" && error.message.indexOf("timeout") !== -1) {
KVA.notifyError('请求超时');
// 这里为啥不写return
}
return Promise.reject(error);
}
);
// request response 响应拦截器
request.interceptors.response.use(async (response) => {
// 在这里应该可以获取服务端传递过来头部信息
// 开始续期
if(response.headers["new-authorization"]){
const userStore = useUserStore()
userStore.setToken(response.headers["new-authorization"])
}
// 包括: 没登录,黑名单,挤下线
if(response.data?.code === 4001 ){
KVA.notifyError(response.data.message);
const userStore = useUserStore()
await userStore.logout()
router.push('/login')
return
}
// cashbin的权限拦截处理
if(response.data?.code === 80001){
KVA.notifyError(response.data.message);
// 如果你想调整页面,就把下面注释打开
//router.push("/nopermission")
return response.data;
}
if(response.data?.code === 20000){
return response.data;
}
const isBlob = response.headers['content-type'].includes('application/octet-stream');
if (isBlob) {
return response;
}
// 所有得服务端得错误提示,全部在这里进行处理
if (response.data?.message) {
KVA.notifyError(response.data.message);
}
// 返回接口返回的错误信息
return Promise.reject(response.data);
},(err) => {
if (err && err.response) {
switch (err.response.status) {
case 400:
err.message = "请求错误";
break;
case 401:
err.message = "未授权,请登录";
break;
case 403:
err.message = "拒绝访问";
break;
case 404:
err.message = `请求地址出错: ${err.response.config.url}`;
break;
case 408:
err.message = "请求超时";
break;
case 500:
err.message = "服务器内部错误";
break;
case 501:
err.message = "服务未实现";
break;
case 502:
err.message = "网关错误";
break;
case 503:
err.message = "服务不可用";
break;
case 504:
err.message = "网关超时";
break;
case 505:
err.message = "HTTP版本不受支持";
break;
default:
}
}
if (err.message) {
KVA.notifyError(err.message);
}
// 判断请求超时
if ( err.code === "ECONNABORTED" && err.message.indexOf("timeout") !== -1) {
KVA.notifyError('服务已经离开地球表面,刷新或者重试...');
}
// 返回接口返回的错误信息
return Promise.reject(err);
})
export default request
配置信息
export default {
method: 'get',
// 基础url前缀
baseURL: import.meta.env.VITE_BASE_API,
// 请求头信息VITE_BASE_PATH
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
// 设置超时时间
timeout: 30000,
// 返回数据类型
responseType: 'json'
}