安装 axios 、 qs
yarn add axios
yarn add qs
复制代码
封装 axios
封装 axios
,由于 axios
是插件所以新建一个 plugins
文件夹来放置:
// ./src/plugins/axios/axiosConfigs.ts
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
import store from '@/store';
import { ElMessage } from "element-plus";
// 创建axios的实例
const service = axios.create({
// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL
baseURL: process.env.NODE_ENV === 'production' ? `/` : '/api',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
},
withCredentials: false, // 跨域请求时是否需要使用凭证
timeout: 30000,
// `validateStatus` 定义对于给定的 HTTP 响应状态码是 resolve 或 reject promise 。
validateStatus() {
// `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
// 使用 async-await,处理 reject 情况较为繁琐,所以全部返回 resolve,在业务代码中处理异常
return true;
},
// `transformResponse` 在传递给 then/catch 前,允许修改响应数据
// transformResponse: [(data) => {
// if (typeof data === 'string' && data.startsWith('{')) {
// data = JSON.parse(data);
// }
// return data;
// }]
});
// 添加请求拦截器
service.interceptors.request.use((config: AxiosRequestConfig) => {
// console.log('发送请求之前', config.url);
// 获取token,并将其添加至请求头中
let token = store.state.user.token;
if(token){
config.headers.Authorization = token;
}
return config;
}, (error: any) => {
console.log('发送请求错误', error.response, error.data);
// 错误抛到业务代码
error.data = {
message: '服务器异常,请联系管理员!'
};
return Promise.reject(error);
});
//添加响应拦截器
service.interceptors.response.use((response: AxiosResponse) => {
// console.log('响应拦截', response.status, response);
/* 处理 http 错误,抛到业务代码 */
const status = response.status;
const decide = status < 200 || status >= 300;
if (decide) {
const message = showStatus(status);
// console.log("处理 http 错误", message);
if (typeof response.data === 'string') {
response.data = { message };
} else {
response.data.message = message;
}
ElMessage({
message,
type: 'error',
showClose: true
})
return Promise.reject(response.data);
}
return response;
}, (error: any) => {
// console.log('请求错误', error, axios.isCancel(error), error.message);
if (axios.isCancel(error)) {
console.log('重复请求: ' + error.message);
} else {
const message = '请求超时或服务器异常,请检查网络或联系管理员!';
ElMessage({
message,
type: 'error',
showClose: true
})
}
return Promise.reject(error);
});
const showStatus = (status: number) => {
let message = '';
switch (status) {
case 400:
message = '请求错误(400)';
break;
case 401:
message = '未授权,请重新登录(401)';
break;
case 403:
message = '拒绝访问(403)';
break;
case 404:
message = '请求出错(404)';
break;
case 408:
message = '请求超时(408)';
break;
case 500:
message = '服务器错误(500)';
break;
case 501:
message = '服务未实现(501)';
break;
case 502:
message = '网络错误(502)';
break;
case 503:
message = '服务不可用(503)';
break;
case 504:
message = '网络超时(504)';
break;
case 505:
message = 'HTTP版本不受支持(505)';
break;
default:
message = `连接出错(${status})!`;
}
return message;
// return `${message},请检查网络或联系管理员!`
};
export default service;
复制代码
设置请求及响应数据格式
设置响应数据格式,设置 get
、 post
等方法的格式:
// ./src/plugins/axios/types.ts
import { AxiosResponse, AxiosRequestConfig } from 'axios';
// 网络请求响应格式,T 是具体的接口返回类型数据
interface CustomSuccessData<T> {
code: number;
msg?: string;
message?: string;
data?: T;
[keys: string]: any;
}
interface Get {
<T>(url: string, config?: AxiosRequestConfig): Promise<CustomSuccessData<T>>;
}
interface Post {
<T>(url: string, params?: string | object, config?: AxiosRequestConfig): Promise<CustomSuccessData<T>>;
}
// ... delete 等等
export {
CustomSuccessData,
Get,
Post
}
复制代码
封装 axios
请求
封装 get
、 post
等方法,使用 request 统一调用:
// ./src/plugins/axios/request.ts
import service from '@/plugins/axios/axiosConfigs'
import { Get, Post } from './types'; // 接口泛型
// 封装 get 方法,类型为Get
const get: Get = async (url, config) => {
const response = await service.get(url, { ...config});
return response.data;
};
const post: Post = async (url, params, config) => {
const response = await service.post(url, params, {...config});
return response.data;
};
// ... delete 等等
// 使用 request 统一调用
const request = {
get,
post
};
export default request;
复制代码
接口配置
配置 api 接口,新增 api
文件夹:
// ./src/api/httpUrl.ts
const config: Api = {
rootUrl: "http://localhost:8080/",
};
const httpApi: Api = {
// 测试接口
banner: config.rootUrl + 'home/banner', // banner
login: config.rootUrl + 'user/login', // 用户登录
}
export default httpApi
复制代码
请求接口配置:
// ./src/api/requestApi.ts
import request from '@/plugins/axios/request'; // axios 封装
import '@/utils/interfaces/AjaxResponse'; // 后端响应数据接口
import '@/utils/interfaces/AjaxRequest'; // 前端请求数据接口
import httpUrl from "./httpUrl"; // 接口 url
import qs from "qs"
// 获取 banner
const getBanner = async () => {
return await request.get<Array<AjaxResponse.Banner>>(httpUrl.banner)
}
// 用户登录
const login = async (params: AjaxRequest.login) => {
return await request.post<string>(httpUrl.login, qs.stringify(params))
}
const handleError = (err: any) => {
// console.log("请求错误", err)
throw err;
}
export {
getBanner,
login,
handleError
}
复制代码
使用
import { getBanner, login, handleError } from '@/api/requestApi'; // 请求接口
export default class Home extends Vue {
mounted(){
console.log("mounted")
const apiTest = async () => {
// get 请求
const banner = await getBanner().catch(handleError)
console.log('banner', banner)
// post 请求
let logintest = await login({
tel: '13192638728',
password: '123456'
}).catch(handleError)
console.log("logintest", logintest)
}
apiTest()
}
}
复制代码
错误测试
把请求头设置为 'Content-Type': 'application/json;charset=utf-8'
,请求 login
接口,报错:
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END