封装api,如何封装axios
墨初 知识笔记 99阅读
作为前端工程师经常需要对axios进行封装以满足复用的目的。在不同的前端项目中使用相同的axios封装有利于保持一致性有利于数据之间的传递和处理。本文提供两种对axios进行封装的思路。
1. 将请求方式作为调用参数传递进来 首先导入了axios, AxiosInstance和AxiosResponse模块
用于创建一个http请求的实例和处理响应结果。定义了一个getBaseUrl函数
用于获取请求的基础URL。创建了httpProto实例
使用axios.create方法
进行创建。并配置了请求的超时时间为5000ms不携带凭证设置请求的Content-Type为application/json;charsetUTF-8
并允许跨域访问。添加了一个请求拦截器通过httpProto.interceptors.request.use
方法对请求进行处理。首先使用getBaseUrl
函数获取基础URL并将其添加到请求的baseURL
属性中。然后通过getToken
函数获取凭证如果凭证存在则将其添加到请求的Authorization
头部字段中。最后返回处理后的请求配置。添加了一个响应拦截器通过httpProto.interceptors.response.use
方法对响应进行处理。首先获取响应的data字段然后判断data.result
的值如果为0则表示请求成功直接返回data。否则将返回一个失败的Promisereject的值为data。定义了一个http
函数用于发送请求。这个函数接收一个method参数和其他参数(rest)
然后通过httpProto[method](...rest)
的形式调用httpProto
实例的对应方法发送请求。定义了一个urls
对象用于存储可供使用的URL路径其中有一个示例路径example。定义了一个methods
对象用于存储常用的请求方法名称包括get、post和delete
。 完整的代码如下所示

import axios, { AxiosInstance, AxiosResponse } from axios;import { getToken } from ./token;// 获取请求的基础URLconst getBaseUrl () > 创建http请求的实例对象const httpProto: AxiosInstance axios.create({ timeout: 5000, withCredentials: false, headers: { Content-Type: application/json;charsetUTF-8, Access-Control-Allow-Origin: *, }});// 添加请求拦截器httpProto.interceptors.request.use((config: any) > { // 配置baseURL config.baseURL getBaseUrl(); // 获取凭证 const token getToken(); if (token) { // 如果有凭证就加上此凭证 config.headers.Authorization ${token}; } return config;}, (error) > { return Promise.reject(error)});// 添加响应拦截器httpProto.interceptors.response.use( (response: AxiosResponse) > { const { data } response // 统一处理响应结果 if (data.result 0) { return data; } else { return Promise.reject(data); } }, (error) > { // 统一处理错误信息 return Promise.reject(error); });// 将httpProto实例也就是AxiosInstance实例对象封装起来const http (method: string, ...rest: any) > { return httpProto[method](...rest);}// 可供使用的urlsconst urls { example: /prod/example,}const methods { get: get, post: post, delete: delete,}export { http, urls, methods };
2. 直接调用某请求方式对应的请求方法 导入了axios
模块的相关类型和函数。定义了printLog
函数用于处理日志输出。定义了IResponse
接口表示请求响应对象的格式。定义了RequestParams
接口表示发送请求的配置项的格式。定义了IHttp
接口表示封装对象支持的请求方式/方法。定义了req
对象用于向外暴露支持的请求方法。定义了methods
数组表示支持的请求方式类型。使用forEach方法遍历methods数组逐步构造req对象上的各个方法。在每个方法的构造过程中进行以下步骤 参数合并
将默认的responseType设置为json。从params对象中解构
需要的参数。使用axios.create
方法创建一个AxiosInstance
实例对象。创建请求头对象
并设置一些常用的请求头信息。构造请求配置对象AxiosRequestConfig
。根据请求方式对请求配置进行修正主要是将data赋值到相应的字段中。添加请求拦截器并在成功和失败的情况下返回配置。添加响应拦截器并在成功和失败的情况下返回处理结果。构造请求成功的回调函数对返回数据进行格式化的操作。构造请求失败的回调函数处理错误日志和断网情况。发送请求并将请求结果作为函数的返回值。默认导出req对象。 以下是加上注释的完整代码
import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from axios;// 日志处理可定制const printLog console;// 作为被Promise包裹的请求响应对象的格式export interface IResponse { code: number; msg: string; result: { lastOperaTime: number; data: any; };}// 发送请求的配置项的格式export interface RequestParams { url: string; baseUrl?: string; data?: object; filter?: boolean; responseType?: arraybuffer | blob | document | json | text | stream; headers?: any; timeout?: number;}// 封装对象支持的请求方式/方法interface IHttp { get?: (params: RequestParams) > Promise<any>; post?: (params: RequestParams) > Promise<any>; put?: (params: RequestParams) > Promise<any>; patch?: (params: RequestParams) > Promise<any>; delete?: (params: RequestParams) > Promise<any>;}// 支持的请求方式类型export type HttpMethod get | post | put | patch | delete;// 向外暴露出去的对象const req: IHttp {};// 支持的请求类型const methods: HttpMethod[] [get, post, put, patch, delete];// 遍历methods数组逐步构造req对象methods.forEach((_m: HttpMethod) > { // 使用遍历的方式对req对象上的各个方法进行构造 req[_m] (params: RequestParams) > { // 1. 构造参数合并 params { ...params, responseType: params.responseType || json, }; // 2. 从使用对象方法的形参上结构出必要的参数 const { url, // 服务器地址 data, // 有效载荷 filter true, // 过滤器 responseType, // 返回类型 timeout, // 超时时间 } params; // 3. 使用axios创建AxiosInstance实例对象 const instance axios.create({ baseURL: params.baseUrl ?? timeout, }); // 4. 创建请求头对象 const headers { lastOperaTime: Date.now(), // 时间戳 token: getToken(), // 凭证 lang: getLocalLocale(), // 语言 Accept: application/json, // 接受返回数据的类型 Content-Type: application/json; charsetutf-8, // 内容格式 }; // 5. 请求配置 const axiosConfig: AxiosRequestConfig { method: _m, // 请求方法 url, // 服务器地址 headers: { // 合并请求头 ...headers, ...(params.headers || {}), }, responseType, // 返回值类型 }; // 6. 针对不同的请求类型需要对请求配置进行修正 if (data) { // 对于有效载荷不同的请求方式携带信息的方式是不同的在这里做了区分 if (_m get) { axiosConfig.params data; } else if (data instanceof FormData) { axiosConfig.data data; } else { axiosConfig.data data; } } // 添加请求拦截器 instance.interceptors.request.use( // 占位 (config: any) > { return config; }, // 失败则返回失败 (error: any) > { return Promise.reject(error); } ); // 7. 添加响应拦截器 instance.interceptors.response.use( // 成功的回调将发起请求的参数作为第二参数回传 (res: any) > handleSuccess(res, params), // 失败的回调将发起请求的参数作为第二参数回传 (err: any) > handleError(err, params) ); // 8. 构造请求成功的回调函数 -- 主要是对返回数据进行格式化的操作 function handleSuccess(response: AxiosResponse<IResponse>, requestParams: RequestParams) { if (response.data) { // 解构数据 const { code, msg, result } response.data; if (code ! 0) { printLog.error(msg); } return filter ? result?.data ?? result : response.data; } else { printLog.error(incorrect data format); return response.data; } } // 9. 构造请求失败的回调函数 function handleError(err: AxiosError, requestParams: RequestParams) { if (err.response) { printLog.error(api: ${requestParams.url}: ${err.response.status}); } if (err instanceof Error) { if (err.message) { printLog.error(err.message); } } if (!window.navigator.onLine) { // 处理断网情况 printLog.error(netwrok error); } return Promise.reject(err); } // 10. 发送请求并将请求结果Promise对象作为函数的返回值 return instance.request(axiosConfig); };});export default req;
给大家推荐一个实用面试题库 1、前端面试题库 面试必备 推荐★★★★★ 地址web前端面试题库

标签: