18 KiB
HTTP 请求模块 (TsHttpUtil)
**本文档引用的文件** - [TsHttpUtil.js](file://src/https/TsHttpUtil.js) - [TsCommon.js](file://src/utils/TsCommon.js) - [TsCrypto.js](file://src/utils/TsCrypto.js) - [TsGlobalConfig.js](file://src/utils/TsGlobalConfig.js) - [TsSM4.js](file://src/utils/TsSM4.js) - [TsStorage.js](file://src/utils/TsStorage.js) - [index.js](file://index.js) - [package.json](file://package.json) - [README.md](file://README.md)目录
简介
HTTP 请求模块 (TsHttpUtil) 是一个基于 umi-request 的网络请求封装库,提供了统一的 HTTP 请求接口,支持 GET、POST 和 FORM 请求方法。该模块集成了参数处理、错误处理、状态码映射、响应数据处理和加密传输等功能,为应用程序提供了一套完整的网络通信解决方案。
该模块的主要特点包括:
- 基于 umi-request 的现代化请求封装
- 智能的参数处理机制(分页器转换、equals 条件处理)
- 统一的错误处理和状态码映射
- 可选的 SM4 加密传输支持
- 与存储模块、加密模块和配置模块的深度集成
项目结构
该项目采用模块化设计,将功能按职责划分为不同的模块:
graph TB
subgraph "核心模块"
Http[TsHttpUtil.js<br/>HTTP请求封装]
Crypto[TsCrypto.js<br/>加密模块]
SM4[TsSM4.js<br/>SM4算法实现]
end
subgraph "工具模块"
Common[TsCommon.js<br/>通用工具函数]
Storage[TsStorage.js<br/>存储模块]
Config[TsGlobalConfig.js<br/>全局配置]
end
subgraph "外部依赖"
UmiRequest[umi-request<br/>HTTP客户端]
Base64[base64-js<br/>Base64编码]
end
Http --> UmiRequest
Http --> Storage
Http --> Common
Http --> Crypto
Http --> Config
Crypto --> SM4
Crypto --> Base64
Crypto --> Config
SM4 --> Base64
图表来源
章节来源
核心组件
主要导出接口
TsHttpUtil 模块提供了四个主要的 HTTP 请求方法:
- req() - 通用请求方法,支持所有 HTTP 方法
- get() - GET 请求方法
- post() - POST 请求方法(JSON 格式)
- form() - 表单提交方法(application/x-www-form-urlencoded)
错误处理机制
模块内置了完善的错误处理系统:
flowchart TD
Request[发起请求] --> Response{收到响应}
Response --> |成功| CheckCode{状态码检查}
Response --> |失败| ErrorHandler[错误处理器]
CheckCode --> |200| ParseData[解析响应数据]
CheckCode --> |其他| HttpError[HTTP错误处理]
ParseData --> EncryptCheck{需要解密?}
EncryptCheck --> |是| Decrypt[解密数据]
EncryptCheck --> |否| ReturnData[返回数据]
Decrypt --> ReturnData
HttpError --> OnError[调用onHttpError回调]
OnError --> Reject[拒绝Promise]
ErrorHandler --> ReturnError[返回标准错误对象]
ReturnError --> Reject
图表来源
章节来源
架构概览
整体架构设计
graph TB
subgraph "应用层"
Client[业务代码]
end
subgraph "HTTP层"
TsHttpUtil[TsHttpUtil]
Request[umi-request]
end
subgraph "数据处理层"
ParamsHandler[参数处理器]
ResponseHandler[响应处理器]
end
subgraph "安全层"
Crypto[加密模块]
Storage[存储模块]
end
subgraph "配置层"
GlobalConfig[全局配置]
SM4[SM4算法]
end
Client --> TsHttpUtil
TsHttpUtil --> Request
TsHttpUtil --> ParamsHandler
TsHttpUtil --> ResponseHandler
ParamsHandler --> Storage
ResponseHandler --> Crypto
Crypto --> SM4
TsHttpUtil --> GlobalConfig
图表来源
数据流处理流程
sequenceDiagram
participant Client as 客户端
participant HttpUtil as TsHttpUtil
participant ParamsHandler as 参数处理器
participant Crypto as 加密模块
participant Request as umi-request
participant Server as 服务器
Client->>HttpUtil : 发起请求
HttpUtil->>ParamsHandler : 处理参数
ParamsHandler->>ParamsHandler : 分页器转换
ParamsHandler->>ParamsHandler : equals条件处理
ParamsHandler->>ParamsHandler : 添加额外参数
alt 需要加密
ParamsHandler->>Crypto : 加密数据
Crypto->>Crypto : SM4加密
Crypto-->>ParamsHandler : 返回加密数据
end
ParamsHandler-->>HttpUtil : 返回处理后的参数
HttpUtil->>Request : 发送HTTP请求
Request->>Server : HTTP请求
Server-->>Request : HTTP响应
Request-->>HttpUtil : 响应数据
alt 响应需要解密
HttpUtil->>Crypto : 解密响应
Crypto->>Crypto : SM4解密
Crypto-->>HttpUtil : 返回明文数据
end
HttpUtil-->>Client : 返回处理后的数据
图表来源
详细组件分析
参数处理机制
分页器转换
模块支持智能的分页器参数转换:
| 输入参数 | 输出参数 |
|---|---|
| pagination.pageSize | pageSize |
| pagination.current | pageNum |
| pagination | 删除 |
equals 条件处理
equals 对象会被转换为逗号分隔的字符串:
// 输入
{ equals: { id: 1, name: 'test' } }
// 输出
{ equals: "id=1,name=test" }
额外参数添加
根据请求类型自动添加额外参数:
- GET 请求: 合并到
params对象 - POST 请求: 合并到
data对象 - 表单请求: 合并到
data对象
章节来源
加密传输支持
加密配置
加密功能通过全局配置启用:
// 启用加密
TsGlobalConfig.setConfig({
encryptBody: true,
base64Key: "your-base64-key"
});
加密流程
flowchart LR
Plain[明文数据] --> JSON[JSON序列化]
JSON --> SM4[SM4加密]
SM4 --> Base64[Base64编码]
Base64 --> Encrypted[加密数据]
Encrypted --> Send[发送到服务器]
Send --> Receive[接收响应]
Receive --> Decrypt[SM4解密]
Decrypt --> Parse[JSON解析]
Parse --> Plain
图表来源
章节来源
错误处理策略
状态码映射
模块内置了常用 HTTP 状态码的中文描述:
| 状态码 | 描述 |
|---|---|
| 200 | 服务器成功返回请求的数据 |
| 201 | 新建或修改数据成功 |
| 202 | 一个请求已经进入后台排队(异步任务) |
| 204 | 删除数据成功 |
| 400 | 发出的请求有错误,服务器没有进行新建或修改数据的操作 |
| 401 | 用户没有权限(令牌、用户名、密码错误) |
| 403 | 用户得到授权,但是访问是被禁止的 |
| 404 | 发出的请求针对的是不存在的记录,服务器没有进行操作 |
| 406 | 请求的格式不可得 |
| 410 | 请求的资源被永久删除,且不会再得到的 |
| 422 | 当创建一个对象时,发生一个验证错误 |
| 500 | 服务器发生错误,请检查服务器 |
| 502 | 网关错误 |
| 503 | 服务不可用,服务器暂时过载或维护 |
| 504 | 网关超时 |
错误处理流程
flowchart TD
Start[请求开始] --> TryRequest[尝试请求]
TryRequest --> Success{请求成功?}
Success --> |是| CheckStatus{状态码检查}
Success --> |否| NetworkError[网络错误处理]
CheckStatus --> Status200{状态码=200?}
Status200 --> |是| ParseResponse[解析响应]
Status200 --> |否| HttpError[HTTP错误处理]
ParseResponse --> EncryptCheck{需要解密?}
EncryptCheck --> |是| Decrypt[解密数据]
EncryptCheck --> |否| ReturnSuccess[返回成功结果]
Decrypt --> ReturnSuccess
HttpError --> CallCallback[调用onHttpError回调]
CallCallback --> ReturnError[返回错误对象]
NetworkError --> ReturnError
ReturnSuccess --> End[请求结束]
ReturnError --> End
图表来源
章节来源
API 接口说明
get() 方法
方法签名
async function get(url, params = {}, options = {})
参数说明
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| url | string | 是 | - | 请求的URL地址 |
| params | object | 否 | {} | GET请求参数 |
| options | object | 否 | {} | 请求选项 |
返回值
{
data: any, // 响应数据
recordsTotal: number // 总记录数
}
使用示例
// 基本使用
const result = await HttpUtil.get('/api/users');
// 带参数使用
const result = await HttpUtil.get('/api/users', {
page: 1,
size: 10,
name: '张三'
});
// 自定义选项
const result = await HttpUtil.get('/api/users', {}, {
timeout: 5000,
headers: {'Authorization': 'Bearer token'}
});
post() 方法
方法签名
async function post(url, data = {}, options = {})
参数说明
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| url | string | 是 | - | 请求的URL地址 |
| data | object | 否 | {} | POST请求数据 |
| options | object | 否 | {} | 请求选项 |
返回值
{
data: any, // 响应数据
recordsTotal: number // 总记录数
}
使用示例
// 基本使用
const result = await HttpUtil.post('/api/users', {
name: '张三',
age: 25
});
// 表单数据
const result = await HttpUtil.post('/api/login', {
username: 'admin',
password: 'password'
}, {
requestType: 'form'
});
form() 方法
方法签名
async function form(url, data = {}, options = {})
参数说明
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| url | string | 是 | - | 请求的URL地址 |
| data | object | 否 | {} | 表单数据 |
| options | object | 否 | {} | 请求选项 |
返回值
{
data: any, // 响应数据
recordsTotal: number // 总记录数
}
使用示例
// 表单提交
const result = await HttpUtil.form('/api/upload', {
file: fileInput.files[0],
description: '文件描述'
});
req() 方法
方法签名
async function req(url, options)
参数说明
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| url | string | 是 | - | 请求的URL地址 |
| options | object | 是 | {} | 请求选项 |
请求选项参数
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| method | string | 否 | 'GET' | HTTP方法 |
| params | object | 否 | {} | GET参数 |
| data | object | 否 | {} | 请求数据 |
| requestType | string | 否 | 'json' | 请求类型 ('json' 或 'form') |
| headers | object | 否 | {} | 请求头 |
| rawResponse | boolean | 否 | false | 是否返回原始响应 |
使用示例
// 自定义请求
const result = await HttpUtil.req('/api/data', {
method: 'POST',
data: {key: 'value'},
headers: {'Custom-Header': 'value'}
});
章节来源
集成关系
与存储模块的集成
TsHttpUtil 通过存储模块管理用户认证信息:
classDiagram
class TsHttpUtil {
+getUserToken() string
+saveUserToken(token) void
+getEncryptBody() boolean
+saveEncryptBody(bool) void
}
class TsStorage {
+getUserToken() string
+saveUserToken(token) void
+getEncryptBody() boolean
+saveEncryptBody(bool) void
}
class TsHttpUtil {
+headers : object
+token : string
}
TsHttpUtil --> TsStorage : 使用
图表来源
与加密模块的集成
加密功能通过 TsCrypto 和 TsSM4 实现:
classDiagram
class TsHttpUtil {
+encryptData(data) object
+decryptData(data) string
}
class TsCrypto {
+encrypt(content) string
+decrypt(base64) string
}
class TsSM4 {
+encrypt(plaintext) string
+decrypt(ciphertext) string
}
class TsGlobalConfig {
+base64Key : string
}
TsHttpUtil --> TsCrypto : 使用
TsCrypto --> TsSM4 : 使用
TsCrypto --> TsGlobalConfig : 读取配置
图表来源
与配置模块的集成
全局配置管理:
classDiagram
class TsGlobalConfig {
+defaultConfig : object
+getConfig() object
+setConfig(obj) void
}
class TsHttpUtil {
+prefix : string
+httpParams : function
+onHttpError : function
}
TsHttpUtil --> TsGlobalConfig : 读取配置
TsGlobalConfig --> TsHttpUtil : 提供配置
图表来源
章节来源
依赖关系分析
外部依赖
项目的主要外部依赖包括:
| 依赖包 | 版本 | 用途 |
|---|---|---|
| umi-request | 1.4.0 | HTTP 客户端库 |
| base64-js | 1.5.1 | Base64 编码/解码 |
内部模块依赖
graph TD
TsHttpUtil[TsHttpUtil.js] --> TsStorage[TsStorage.js]
TsHttpUtil --> TsCommon[TsCommon.js]
TsHttpUtil --> TsCrypto[TsCrypto.js]
TsHttpUtil --> TsGlobalConfig[TsGlobalConfig.js]
TsCrypto --> TsSM4[TsSM4.js]
TsCrypto --> TsGlobalConfig
TsSM4 --> Base64[base64-js]
index[index.js] --> TsHttpUtil
index --> TsStorage
index --> TsCrypto
index --> TsGlobalConfig
index --> TsSM4
index --> TsCommon
图表来源
章节来源
性能考虑
请求优化建议
- 批量请求: 对于多个相关的请求,考虑合并到单个请求中以减少网络开销
- 缓存策略: 在业务层实现适当的缓存机制,避免重复请求相同数据
- 超时设置: 合理设置请求超时时间,避免长时间阻塞
- 压缩传输: 对大体积数据考虑使用压缩算法
内存管理
- 及时清理不再使用的响应数据
- 避免在请求过程中创建大量临时对象
- 注意循环引用的处理
故障排除指南
常见问题及解决方案
1. 认证失败
症状: 返回 401 状态码
原因: 用户令牌无效或过期
解决方案:
// 检查用户令牌
const token = Storage.getUserToken();
if (!token) {
// 重新登录
redirectToLogin();
}
// 设置自定义头部
const result = await HttpUtil.get('/api/protected', {}, {
headers: {
'Authorization': `Bearer ${token}`
}
});
2. 数据解密失败
症状: 解密后数据格式错误
原因: 加密密钥不匹配或数据损坏
解决方案:
// 检查加密配置
const encryptEnabled = Storage.getEncryptBody();
if (encryptEnabled) {
// 验证密钥配置
const config = GlobalConfig.getConfig();
if (!config.base64Key) {
throw new Error('缺少加密密钥配置');
}
}
3. 请求超时
症状: 请求长时间无响应
原因: 网络延迟或服务器负载过高
解决方案:
try {
const result = await HttpUtil.get('/api/data', {}, {
timeout: 10000 // 10秒超时
});
} catch (error) {
if (error.code === 'ECONNABORTED') {
// 处理超时
showTimeoutMessage();
}
}
4. 参数格式错误
症状: 返回 400 状态码
原因: 请求参数格式不符合服务器要求
解决方案:
// 使用分页器参数
const result = await HttpUtil.get('/api/list', {
pagination: {
pageSize: 10,
current: 1
}
});
// 使用 equals 条件
const result = await HttpUtil.get('/api/search', {
equals: {
status: 'active',
type: 'user'
}
});
章节来源
结论
HTTP 请求模块 (TsHttpUtil) 提供了一个功能完整、易于使用的网络请求封装解决方案。其主要优势包括:
- 统一的接口设计: 提供简洁一致的 API 接口
- 智能参数处理: 自动处理分页器和条件参数
- 完善的错误处理: 内置状态码映射和错误回调机制
- 灵活的安全支持: 可选的 SM4 加密传输功能
- 良好的模块化: 与存储、加密、配置模块的深度集成
该模块适合在企业级应用中使用,能够有效简化网络请求的处理逻辑,提高开发效率和代码质量。通过合理的配置和使用,可以满足大多数 Web 应用的网络通信需求。