基础概念
在 umi 项目中并没有规定一定要使用某种 http 请求方式,我们可以根据实际项目,选择自己最熟悉和服务端交互最优的 http 请求方式,一般项目中我们比较常用的就是 fetch 和 axios ,这两者的优缺点比较,可以查阅其他资料,但是无论你选择哪一种,在你需要更换成另一种时,只需要修改几行代码,因为它们在使用上,只有一点点参数结构的差异。
在ant design Pro中直接使用了umi-request,我们可以通过request.tx对请求进行统一的拦截和过滤处理,request.ts所在目录:/src/utils/request.ts
引入umi-request:
import { extend } from 'umi-request';
异常处理程序
/** 异常处理程序 */const errorHandler = (error: { response: Response }): Response => {const { response } = error;if (response && response.status) {const errorText = codeMessage[response.status] || response.statusText;const { status, url } = response;notification.error({message: `请求错误 ${status}: ${url}`,description: errorText,});} else if (!response) {notification.error({description: '您的网络发生异常,无法连接服务器',message: '网络异常',});}return response;};
配置request请求时的默认参数
/** 配置request请求时的默认参数 */const request = extend({prefix: "/api",// baseURL: process.env.VUE_APP_API_BASE_URL,errorHandler, // 默认错误处理credentials: 'include', // 默认请求是否带上cookietimeout: requestTimeOut,responseType: 'json',});
请求拦截器
request.interceptors.request.use(async (url, options) => {const headers = options.headers;if(headers['Authorization']==''||headers['Authorization']==null){const expireTime = localStorage.getItem("expireTime")if (expireTime) {const left = Number(expireTime) - new Date().getTime()const refreshToken = localStorage.getItem("refresh_token")if (left < checkRegion && refreshToken) {if (left < 0) {localStorage.removeItem("expireTime");localStorage.removeItem("refresh_token");localStorage.removeItem("access_token");}let accessToken = queryRefreshToken(refreshToken);headers['Authorization'] = 'bezarer ' + accessToken;} else {const accessToken = localStorage.getItem("access_token");if (accessToken) {headers['Authorization'] = 'bearer ' + accessToken;}}}}return ({url: url,options: { ...options, headers: headers },});})
响应拦截器
request.interceptors.response.use((response, options) => {//拦截返回后的特殊处理// if(response.data.code == 1000001){// console.log(response.data.msg)// //通过返回的code 提示 token 过期 、token校验失败,做相应跳转// }console.log(response)return response;});
请求使用案例
新建功能模块后,在模块目录下新建service.ts 用于封装请求信息。
我们以角色信息模块为案例,介绍对应的使用,角色service.ts所在目录:/src/pages/system/role/service.ts
import request from '@/utils/request';import querystring from 'querystring'import type { TableListParams, TableListItem } from './data.d';export async function queryData(params?: TableListParams) {let queryString = querystring.stringify(params);return request('/system/role/findListPage?'+queryString, {data: params,method: 'get',headers: {'Content-Type': 'application/json;charset=UTF-8',}});}export async function removeData(params: { ids: string[] }) {return request('/system/role/'+params.ids, {method: 'delete',headers: {'Content-Type': 'application/json;charset=UTF-8',}});}export async function addData(params: TableListItem) {return request('/system/role', {method: 'POST',data: {...params,method: 'post',},});}export async function updateData(params: TableListParams) {return request('/system/role', {method: 'PUT',data: {...params,method: 'update',},});}//更新状态export async function updateStatus(id:string,status:string) {return request('/system/role/updateStatus', {method: 'post',data: {id,status}});}//更新权限export function updateAuth (params:any) {return request('/system/role/updateAuth', {method: 'post',data: {...params}});}//获取角色菜单列表export function findRoleMenuList (params:any) {return request('/system/role/findRoleMenuList', {data: params,method: 'post'});}
在上面的代码中使用了:post请求、get请求、put请求、delete请求。
post请求
post请求一般处理数据的保存操作,比如角色信息的保存提交。
return request('/system/role', {method: 'POST',data: {...params,method: 'post',},});
get请求
get请求一般处理数据的查询操作,比如查询角色信息的列表信息、详情信息等等。
return request('/system/role', {method: 'POST',data: {...params,method: 'post',},});
put请求
put请求一般处理数据的更新操作,比如角色信息的更新数据。
return request('/system/role', {method: 'PUT',data: {...params,method: 'update',},});
delete请求
delete请求一般处理数据的删除操作,比如角色信息的删除。
return request('/system/role/'+params.ids, {method: 'delete',headers: {'Content-Type': 'application/json;charset=UTF-8',}});
