@bud-fe/request
v2.0.5
Published
百威前端网络请求库
Downloads
949
Keywords
Readme
@bud-fe/request
百威前端网络请求库
✨ 特性
- 提供了对基于
axios
、Taro
的配置封装、基础&重复请求的拦截器预设 - 支持针对 response 错误的自定义处理
axios
封装了下载的功能
📦 安装
$ pnpm add @bud-fe/request
🔨 使用
Axios
0. 确保已安装 axios
$ pnpm add axios@^1.2.1
1. 创建 request 实例
import AxiosRequest, { TAxiosExtConfig } from '@bud-fe/request/es/axios';
import { authHelper } from '@bud-fe/utils';
import { message } from 'antd';
import type { MessageType } from 'antd/lib/message';
import type { AxiosRequestConfig } from 'axios';
// axios 配置
const requestConfig: AxiosRequestConfig = {
baseURL: 'https://one-crm-dev.ab-inbev.cn',
// ...axios中的所有配置项
};
let messageHide: MessageType;
// 额外配置
const extConfig: TAxiosExtConfig = {
// 可选,设置重复请求策略,值为:disabled | useCurrent | usePrevious,默认为 usePrevious
// disabled: 不对重复请求做额外处理; useCurrent: 取消上一次未结束的而使用当前触发的;usePrevious: 取消当下触发的而使用上次未结束的
// 如果某些接口需要改变 repeatMode, 也可以在具体的接口方法里传参重置
repeatMode: 'usePrevious',
// 可选。全局请求中的回调。可以在此处展示 loading UI
onLoadingStatusChanged: (requestInfo) => {
console.log('onLoading===', requestInfo);
messageHide = message.loading('加载中...');
},
// 可选。token header key,可传string或者函数
// NOTE: 与 authHelper 二选一
tokenName: authHelper.getTokenName,
// 可选。@bud-fe/utils 中的 authHelper
// NOTE: 与 tokenName 二选一
authHelper,
// 可选。绕过重复请求拦截的 url
bypassRepeatInterceptUrls: [],
// 可选。所有请求的 response 回调
responseAction: {
default: (msg, detailInfo) => {
// 处理默认错误的回调,可以在此处toast提示用户
message.error(msg);
},
repeat: (msg) => {
// 处理拦截重复请求的回调,可以在此处toast提示用户
// note: 如果设置了 repeatMode 为 disabled || useCurrent 时,该设置不会生效
message.error(msg);
},
complete: (detailInfo) => {
// 请求完成后的回调,一般用于埋点
console.log('complete===', detailInfo);
messageHide?.();
},
401: (msg, detailInfo) => {
// 处理code为 401 的回调,可以在此处做跳转处理
},
// ...其余非200业务code的回调
},
};
const request = new AxiosRequest(requestConfig, extConfig);
添加拦截器(可选)
request.addInterceptor({
request: {
onConfig: (config) => {
return config;
},
onError: (error) => {
return Promise.reject(error);
},
},
response: {
onConfig: (response) => {
return response;
},
onError: (error) => {
return Promise.reject(error);
},
},
});
2. 调用 request 实例的函数
request
.post<IUserInfo>('/user/console/login', { username: 'admin', password: '123456' })
.then((res) => {
console.log('res.code', res.code);
console.log('res.data', res.data);
console.log('res.message', res.message);
})
.catch((e) => console.log(e));
// 单个请求设置重复策略覆盖初始设置:
request.post<IUserInfo>('/user/console/login', { username: 'admin', password: '123456' }, null, {
repeatMode: 'useCurrent',
});
// request.get 用法同上
// request.download 用法同上
Taro
0. 确保已安装 @tarojs/taro
$ pnpm add @tarojs/taro
1. 创建 request 实例
import TaroRequest from '@bud-fe/request/es/taro';
import { getBaseUrl } from '@/configs';
import type { ITaroExtConfig, TGlobalOptionType } from '@bud-fe/request/es/taro';
import Taro from '@tarojs/taro';
// token header key
const HEADER_KEY_TOKEN = 'Authorization';
const COMMON_HEADER = {
// ...定义全局 header
};
// 全局的请求配置,包括 baseURL(可传函数)、全局 header
const globalOption: TGlobalOptionType = {
baseURL: getBaseUrl,
header: COMMON_HEADER,
};
// 额外配置
const globalExtConfig: ITaroExtConfig = {
// 必传。token header key,可传 string 或函数
tokenName: HEADER_KEY_TOKEN,
// 可选。绕过重复请求拦截的 url
bypassRepeatInterceptUrls: [],
// 可选。所有请求的 response 回调
responseAction: {
// 默认错误的回调,可以在此处 toast 提示用户
default: (msg, detailInfo) => {
Taro.showToast({ title: `默认错误-${msg}`, icon: 'none' });
},
// 拦截重复请求的回调,可以在此处 toast 提示用户
repeat: (msg, detailInfo) => {
Taro.showToast({ title: `重复拦截错误-${msg}`, icon: 'none' });
console.log('repeat===', detailInfo);
},
complete: (detailInfo) => {
// 请求完成后的回调,一般用于埋点
console.log('complete===', detailInfo);
},
// code 为 401 的回调,可以在此处做跳转处理
401: (msg) => {
Taro.reLaunch({ url: `/pages/login/index?msg=${msg}` });
},
},
// 当需要自定义全局loading UI时传入。
// 已解决IPhone上toast和loading共用一个实例的问题
// 已做去重
onLoadingStatusChanged: (show) => {
if (show) {
Taro.showLoading({ title: '加载中...' });
} else {
Taro.hideLoading();
}
},
// 可选。小程序静默登录相关配置。TODO: 若不使用小程序静默登录,请删除
silentLoginConfig: {
/**
* 不触发静默登录的接口url列表。建议相对路径
*/
bypassUrls: [],
/**
* 触发静默登录的时机(无论哪种mode,接口请求401无权限时都会触发)
* 'no-token' - 请求前判断storage中有无token,无则触发; 'no-auth' - 接口请求401无权限时触发
* @default 'no-token'
*/
triggerMode: 'no-token',
/**
* 执行业务登录接口逻辑的 Promise。需要返回一个token值,其余情况视为失败
* @param loginResult Taro.login 返回的结果
* @returns 业务登录接口返回的token值
*/
loginPromise: async (loginResult) => {
// TODO: 请求业务登录接口...
// const res = await request.post('/login', { code: loginResult.code });
return 'token123456';
},
},
};
const request = new TaroRequest(globalOption, globalExtConfig);
2. 调用 request 实例的函数
request
.post<IGetIssueMainResp>(
'/user/console/login',
// 请求参数
{ username: 'admin', password: '123456' },
// 可选。Taro.request 的 option
{ header: {} },
// 可选。
// showLoading - 此请求是否展示loading(默认true)
// showError - 此请求是否回调出错(回调第一步配置的responseAction。默认true)
// bypassRepeatIntercept - 此请求是否绕过重复请求拦截(默认false)
{ showLoading: true, showError: true, bypassRepeatIntercept: false },
)
.catch((e) => console.log(e));
// request.get 用法同上
关于接口加签的配置
在 request 初始化实例传入的 extConfig
中:
const extConfig: TAxiosExtConfig = {
// or const extConfig: TAxiosExtConfig = {
// ...
/**
* 应用标识。参考:{@see https://budtech.yuque.com/beqo6k/pf0gar/gcp49tsu0f5oqo4m#EwFR}
* 如果是全新的应用,需联系后端同学协商好具体值
*/
appId: 'mpconsole',
/**
* 应用是toB(api.gateway)还是toC(capi.gateway)。
* 'business': B端 'consumer': C端
* @default 'business'
*/
serviceType: 'business',
};
1. 一些特殊情况的处理
如果存在以下两种情况,还需要在
extConfig
中配置originUrl
:- request 配置的
baseURL
是中台的网关地址、但携带了服务 path - request 配置的
baseURL
不是中台的网关地址(api-gateway/capi-gateway)
const requestConfig: AxiosRequestConfig = { // or const globalOption: TGlobalOptionType = { // case1: 这里的 baseURL 携带了 /xxx-service 这一段 path baseURL: 'https://api-gateway-feature-5.ab-inbev.cn/xxx-service', // case2: 这里的 baseURL 不是中台的网关地址 baseURL: 'https://brand-miniprogram-service-api-hotfix.ab-inbev.cn', }; const extConfig: TAxiosExtConfig = { // or const extConfig: TAxiosExtConfig = { // ... /** * 接口的网关地址(不要携带服务path) */ // B端 originUrl: 'https://api-gateway-feature-5.ab-inbev.cn', // C端 originUrl: 'https://capi-gateway-feature-5.ab-inbev.cn', // ... };
- request 配置的
~~2. 在钉钉端各别机型会报 replaceAll is not a function
的错误,原因是内部使用的 query-string
库中用到了 String
的replaceAll
(ES2021)方法。如果碰到这个错误,需要自行在 String
的原型中挂上 replaceAll
:~~
2. 构建过程中碰到的警告处理
ice3 项目
pnpm start
时会报Can't resolve 'crypto' ...
的警告(但是不影响使用),可以在ice.config.mts
中添加以下配置忽略掉警告:// ... const mode = process.env.ICE_CORE_MODE || ''; const commonWebpackConfig = (webpackConfig: Configuration) => { // 新增代码 ⬇️ webpackConfig.ignoreWarnings = [ (warning) => { if (/Can't resolve 'crypto'.+@bud-fe\/request/.test(warning.message)) { return true; } return false; }, ]; // 新增代码 ⬆️ // ...
Taro (>= v3.6) 项目 构建时会报
Can't resolve 'crypto' ...
的警告(但是能构建出产物),可以在config/index.js
中添加以下配置忽略掉警告:// ... mini: { webpackChain(chain) { chain.merge({ ignoreWarnings: [ { message: /resolve 'crypto'/, module: /bud-fe\/request/, }, ], }); } // ... }