开门见山
在根目录创建一个api文件夹,在api文件夹下创建一个名为service.js的文件,用来进行axios封装。
1.既然要封装axios,首先就要下载axios插件库
npm install axios
2.引入了axios后,现在正式开始对它进行封装了。
service.js中
import axios from 'axios'
//创建请求函数
function request(config) {
// 创建一个名为instance的axios实例
const instance = axios.create({
// 配置请求地址
baseURL: import.meta.env.VITE_APP_API_BASEURL,
// 设置超时时间
timeout: 5000,
})
return instance(config)
}
这里的instance
就是axios的实例,后面要对它进行许多操作
3 .继续进行操作:配置请求头
根据需要进行配置
instance.interceptors.request.use((config) => {
// 配置请求头
if (userStore.isLogin && !request.removeAuth) {
request.headers['Authorization'] = userStore.token
}
return config
})
一般情况请求后端接口要跟上一个token。有的使用到的是Authorization、有的是bear、根据需求进行修改。
4 . 对返回结果进行拦截(拦截response)
instance.interceptors.response.use(
(response) => {
const dataAxios = response.data
const { code, data } = dataAxios
// 目前和后端口头约定是字符串,以防万一强制转字符串
switch (`${code}`) {
// code === 200 | 2 代表没有错误
case '200':
case '2':
return data
// code === 400001004 代表token 过期打回登录页
case '40001':
throttleToLogin()
break
case '40002':
case '40003':
// 不是正确的 code
return requestError(response)
default:
// 不是正确的 code
return requestError(response)
}
},
(error) => {
// 这里的这个get用到的是lodash-es,用来获取error.response.status的,如果没有这个key的话就是undefined
// httpLogError:记录错误日志的一个方法
const status = get(error, 'response.status')
switch (status) {
case undefined:
case null:
httpLogError(error, '网路错误或请求跨域')
break;
case 400:
httpLogError(error, '请求错误')
break;
case 404:
httpLogError(error, `请求地址出错: ${error.response.config.url}`);
break;
default:
httpLogError(error, "请求错误");
break;
}
ElMessage({
message: error.message,
type: 'error'
})
return Promise.reject(error)
}
)
当请求结果返回的时候做了这些处理:
- 用
dataAxios
接受返回结果中的data(这里的data还是要根据后端给你的结构去灵活修改) - 结构拿出来
dataAxios
中的code
和data
(同上)(注意:这里的code也是和后端约定校验规则的) switch
去判断code
,只有在code
是200
和2
的时候 返回data(仍然注意code也是约定的, 我这里的200
和2
也是和后端商量好后写上去的)- 其他情况的话 执行
requestError
方法进行错误处理
catch
里进行错误处理,根据返回的code或者错误码进行错误处理- 最后进行返回
reject
,以便以后在api请求中的catch
中查看问题。
5.锦上添花 requestError
function requestError(response) {
return new Promise((_, reject) => {
const { data } = response;
const msg = __DEV__ ? `api请求出错 ${response.config.url}` : data.msg;
ElMessage({
message: msg,
type: "error",
});
reject(data);
});
}
- 返回一个 Promise 对象。
- 从响应对象中获取错误信息。
- 根据开发环境的设置生成不同的错误提示信息。
- 使用消息组件显示错误提示。
- 将错误信息传递给调用方进行进一步处理。(也可以不传,就当一个提示)
6. 文件内容:
// service.js
import axios from "axios";
import { ElMessage } from "element-plus";
import { userStore } from "@/stores/user.js";
function requestError(response) {
return new Promise((_, reject) => {
const { data } = response;
const msg = __DEV__ ? `api请求出错 ${response.config.url}` : data.msg;
ElMessage({
message: msg,
type: "error",
});
reject(data);
});
}
export function request(config) {
// 设置请求配置
const instance = axios.create({
baseURL: import.meta.env.VITE_APP_API_BASEURL,
timeout: 5000,
});
instance.interceptors.request.use((config) => {
// 配置请求头
const userData = userStore();
if (userStore.isLogin && !request.removeAuth) {
request.headers["Authorization"] = userStore.token;
}
return config;
});
instance.interceptors.response.use(
(response) => {
const dataAxios = response.data;
const { code, data } = dataAxios;
// 目前和公司后端口头约定是字符串,以防万一强制转字符串
switch (`${code}`) {
// code === 200 | 2 代表没有错误
case "200":
case "2":
return data;
// code === 400001004 代表token 过期打回登录页
case "400001":
// 打回登录页等方法,要根据情况修改
throttleToLogin();
break;
case "400002":
case "400003":
// 不是正确的 code
return requestError(response);
default:
// 不是正确的 code
return requestError(response);
}
},
(error) => {
const status = get(error, "response.status");
switch (status) {
// TODO 再考虑下怎么判断是跨域问题
case undefined:
case null:
httpLogError(error, "网路错误或请求跨域");
break;
case 400:
httpLogError(error, "请求错误");
break;
case 401:
httpLogError(error, "未授权,请登录");
break;
case 403:
httpLogError(error, "拒绝访问");
break;
case 404:
httpLogError(error, `请求地址出错: ${error.response.config.url}`);
break;
default:
httpLogError(error, "请求错误");
break;
}
ElMessage({
message: error.message,
type: "error",
});
return Promise.reject(error);
}
);
return instance(config);
}
一定要根据需求去修改:比如token
、userStore
等等