@navalink/request
v2.0.2
Published
Dogesoft 业务请求封装库。
Readme
Request
Dogesoft 业务请求封装库。
Install
# with npm
npm i @ @navalink/request
# with yarn
yarn add @navalink/requestUsage
基本使用
import $http, { EApiStatus, IResponse } from '@navalink/request';
const refreshTokenOften = async () => {
const result = await $http.post<any, IResponse<any>>(`/api/xxx/xxx`);
if (result.status === EApiStatus.success) {
const data = result.data;
// ...
}
}传入配置
某些场景下需要修改 axios 基础配置信息,比如 file-system 会在桌面端环境下使用不同的 url origin。
import { injectCustomization } from '@navalink/request';
injectCustomization({
config: {
baseURL: 'https://xxx.com',
},
});传递固定参数
在一些工程下,需要在每个接口内传递特定参数,比如 doty-roster 2.0 传递 app_id 信息。
import { injectCustomization } from '@navalink/request';
injectCustomization({
baseData: {
app_id: 'app_id value'
}
});定制 Response
通常,我们会根据后台接口下发的 code 区分做不同处理,比如:登录失效、没有权限等。
import { EApiStatus, injectCustomization } from '@navalink/request';
injectCustomization({
listenResponse: (result, response) => {
if (result.status === EApiStatus.tokenInvalid) {
alert('请重新登录!');
}
}
});动态设置 baseData
import { injectBaseData } from '@navalink/request';
injectBaseData({
role: 'role',
});2.0.0 的重大变更
2.0.0 升级了 axios,由 0.21.1 升级到了 1.8.3
axios 升级后产生的影响:
axios 从 0.21.4 升级到 1.8.3:
⭕️ 一、axios 1.8.3 新版特性中对现有代码产生影响的变更、及修改方案:
1、升级后的 axios 自动将请求体序列化为:
⭕️ JSON (application/json)
Multipart / FormData (multipart/form-data)
URL encoded form (application/x-www-form-urlencoded)
⭕️ 将 HTML Form 转换成 JSON 进行请求
自动转换JSON数据
- ⭕️ 只有当请求头中的 Content-Type 是 multipart/form-data 时,Axios 才会自动地将普通对象序列化成一个 FormData 对象。
产生的影响:
对于没有设置 Content-Type multipart/form-data, 即便以 FormData 形式传输的参数接,也会被自动转成 application/json 格式。
解决方案:
在请求头中设置 content-type 为 multipart/form-data;
const options = {
method: "POST",
headers: { "content-type": "multipart/form-data" }, // 明确设置Content-Type
data: file.formData,
url,
};
axios(options);
或:
$http.post<any, IResponse<IResource>>('/api/files/upload', file.formData, {
...config,
headers: {
...config.headers,
'Content-Type': 'multipart/form-data' // 明确设置Content-Type
},
adapter: customXhrUpload as AxiosAdapter
});
⭕️ 2、对进度时间的处理方式进行了改变。Axios 0.X 版本直接使用浏览器的 ProgressEvent 对象,而 1.X 版本则使用自定义的 AxiosProgressEvent 对象。
0.X 版本:
// 直接使用浏览器的 ProgressEvent
interface AxiosRequestConfig {
onDownloadProgress?: (progressEvent: ProgressEvent) => void;
onUploadProgress?: (progressEvent: ProgressEvent) => void;
}
1.X 版本:
// 自定义了 AxiosProgressEvent 接口
interface AxiosProgressEvent {
loaded: number;
total?: number;
progress?: number; // 0-1 之间的数值
bytes: number; // 新增字段
estimated?: number;
rate?: number;
upload?: boolean;
download?: boolean;
}
interface AxiosRequestConfig {
onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void;
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
}
所以如果代码中有用到 AxiosRequestConfig onDownloadProgress、onUploadProgress 的地方,可能会有如下报错:
没有与此调用匹配的重载。
第 1 个重载(共 2 个),“(type: "progress", listener: (this: XMLHttpRequest, ev: ProgressEvent<XMLHttpRequestEventTarget>) => any, options?: boolean | ... 1 more ... | undefined): void”,出现以下错误。
类型“(progressEvent: AxiosProgressEvent) => void”的参数不能赋给类型“(this: XMLHttpRequest, ev: ProgressEvent<XMLHttpRequestEventTarget>) => any”的参数。
参数“progressEvent”和“ev” 的类型不兼容。
类型 "ProgressEvent<XMLHttpRequestEventTarget>" 中缺少属性 "bytes",但类型 "AxiosProgressEvent" 中需要该属性。
解决方案:
使用新版本的类型定义,如
import { AxiosRequestConfig, AxiosProgressEvent } from 'axios';
interface ICustomConfig extends AxiosRequestConfig {
onDownloadProgress?(progressEvent: AxiosProgressEvent): void;
onUploadProgress?(progressEvent: AxiosProgressEvent): void;
}
function handleProgress(progressEvent: AxiosProgressEvent) {
const percentCompleted = progressEvent.total
? Math.round((progressEvent.loaded * 100) / progressEvent.total)
: 0;
console.log(完成度: ${percentCompleted}%);
console.log(传输速率: ${progressEvent.rate} bytes/s);
console.log(本次传输字节: ${progressEvent.bytes});
}
如需兼容旧代码:
可以 将 config.onDownloadProgress、config.onUploadProgress 的类型定义为 any,如:
xhr.addEventListener('progress', config.onDownloadProgress as any);
xhr.upload.addEventListener('progress', config.onUploadProgress as any);
⭕️ 3、请求拦截器类型定义发生了变化,由 AxiosRequestConfig 变为 InternalAxiosRequestConfig,所以代码上需要把
import { AxiosRequestConfig } from 'axios'; // 如有用到,需要修改
instance.interceptors.request.use((config: AxiosRequestConfig) => { // 如有用到,需要修改
const handleRequestResolve = (config: AxiosRequestConfig) => { // 如有用到,需要修改
改为:
import { InternalAxiosRequestConfig } from 'axios';
instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
const handleRequestResolve = (config: InternalAxiosRequestConfig) => {
⭕️ 4、新版本推荐使用 common 来设置通用头部 instance.defaults.headers.common, 所以
instance.defaults.headers[method]['Content-Type'] = 'application/json; charset=utf-8';
需要改为:
instance.defaults.headers.common["Content-Type"] = 'application/json; charset=utf-8';
