# 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)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构概览](#架构概览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
## 简介
HTTP 请求模块 (TsHttpUtil) 是一个基于 umi-request 的网络请求封装库,提供了统一的 HTTP 请求接口,支持 GET、POST 和 FORM 请求方法。该模块集成了参数处理、错误处理、状态码映射、响应数据处理和加密传输等功能,为应用程序提供了一套完整的网络通信解决方案。
该模块的主要特点包括:
- 基于 umi-request 的现代化请求封装
- 智能的参数处理机制(分页器转换、equals 条件处理)
- 统一的错误处理和状态码映射
- 可选的 SM4 加密传输支持
- 与存储模块、加密模块和配置模块的深度集成
## 项目结构
该项目采用模块化设计,将功能按职责划分为不同的模块:
```mermaid
graph TB
subgraph "核心模块"
Http[TsHttpUtil.js
HTTP请求封装]
Crypto[TsCrypto.js
加密模块]
SM4[TsSM4.js
SM4算法实现]
end
subgraph "工具模块"
Common[TsCommon.js
通用工具函数]
Storage[TsStorage.js
存储模块]
Config[TsGlobalConfig.js
全局配置]
end
subgraph "外部依赖"
UmiRequest[umi-request
HTTP客户端]
Base64[base64-js
Base64编码]
end
Http --> UmiRequest
Http --> Storage
Http --> Common
Http --> Crypto
Http --> Config
Crypto --> SM4
Crypto --> Base64
Crypto --> Config
SM4 --> Base64
```
**图表来源**
- [TsHttpUtil.js:1-171](file://src/https/TsHttpUtil.js#L1-L171)
- [TsCrypto.js:1-34](file://src/utils/TsCrypto.js#L1-L34)
- [TsSM4.js:1-456](file://src/utils/TsSM4.js#L1-L456)
**章节来源**
- [index.js:1-16](file://index.js#L1-L16)
- [package.json:19-22](file://package.json#L19-L22)
## 核心组件
### 主要导出接口
TsHttpUtil 模块提供了四个主要的 HTTP 请求方法:
1. **req()** - 通用请求方法,支持所有 HTTP 方法
2. **get()** - GET 请求方法
3. **post()** - POST 请求方法(JSON 格式)
4. **form()** - 表单提交方法(application/x-www-form-urlencoded)
### 错误处理机制
模块内置了完善的错误处理系统:
```mermaid
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
```
**图表来源**
- [TsHttpUtil.js:25-35](file://src/https/TsHttpUtil.js#L25-L35)
- [TsHttpUtil.js:99-134](file://src/https/TsHttpUtil.js#L99-L134)
**章节来源**
- [TsHttpUtil.js:7-23](file://src/https/TsHttpUtil.js#L7-L23)
- [TsHttpUtil.js:28-35](file://src/https/TsHttpUtil.js#L28-L35)
## 架构概览
### 整体架构设计
```mermaid
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
```
**图表来源**
- [TsHttpUtil.js:1-171](file://src/https/TsHttpUtil.js#L1-L171)
- [TsCrypto.js:1-34](file://src/utils/TsCrypto.js#L1-L34)
- [TsGlobalConfig.js:1-34](file://src/utils/TsGlobalConfig.js#L1-L34)
### 数据流处理流程
```mermaid
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 : 返回处理后的数据
```
**图表来源**
- [TsHttpUtil.js:46-91](file://src/https/TsHttpUtil.js#L46-L91)
- [TsHttpUtil.js:99-134](file://src/https/TsHttpUtil.js#L99-L134)
## 详细组件分析
### 参数处理机制
#### 分页器转换
模块支持智能的分页器参数转换:
| 输入参数 | 输出参数 |
|---------|---------|
| pagination.pageSize | pageSize |
| pagination.current | pageNum |
| pagination | 删除 |
#### equals 条件处理
equals 对象会被转换为逗号分隔的字符串:
```javascript
// 输入
{ equals: { id: 1, name: 'test' } }
// 输出
{ equals: "id=1,name=test" }
```
#### 额外参数添加
根据请求类型自动添加额外参数:
- **GET 请求**: 合并到 `params` 对象
- **POST 请求**: 合并到 `data` 对象
- **表单请求**: 合并到 `data` 对象
**章节来源**
- [TsHttpUtil.js:50-91](file://src/https/TsHttpUtil.js#L50-L91)
### 加密传输支持
#### 加密配置
加密功能通过全局配置启用:
```javascript
// 启用加密
TsGlobalConfig.setConfig({
encryptBody: true,
base64Key: "your-base64-key"
});
```
#### 加密流程
```mermaid
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
```
**图表来源**
- [TsCrypto.js:15-30](file://src/utils/TsCrypto.js#L15-L30)
- [TsSM4.js:338-387](file://src/utils/TsSM4.js#L338-L387)
**章节来源**
- [TsCrypto.js:1-34](file://src/utils/TsCrypto.js#L1-L34)
- [TsSM4.js:96-453](file://src/utils/TsSM4.js#L96-L453)
### 错误处理策略
#### 状态码映射
模块内置了常用 HTTP 状态码的中文描述:
| 状态码 | 描述 |
|-------|------|
| 200 | 服务器成功返回请求的数据 |
| 201 | 新建或修改数据成功 |
| 202 | 一个请求已经进入后台排队(异步任务) |
| 204 | 删除数据成功 |
| 400 | 发出的请求有错误,服务器没有进行新建或修改数据的操作 |
| 401 | 用户没有权限(令牌、用户名、密码错误) |
| 403 | 用户得到授权,但是访问是被禁止的 |
| 404 | 发出的请求针对的是不存在的记录,服务器没有进行操作 |
| 406 | 请求的格式不可得 |
| 410 | 请求的资源被永久删除,且不会再得到的 |
| 422 | 当创建一个对象时,发生一个验证错误 |
| 500 | 服务器发生错误,请检查服务器 |
| 502 | 网关错误 |
| 503 | 服务不可用,服务器暂时过载或维护 |
| 504 | 网关超时 |
#### 错误处理流程
```mermaid
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
```
**图表来源**
- [TsHttpUtil.js:7-23](file://src/https/TsHttpUtil.js#L7-L23)
- [TsHttpUtil.js:28-35](file://src/https/TsHttpUtil.js#L28-L35)
- [TsHttpUtil.js:117-128](file://src/https/TsHttpUtil.js#L117-L128)
**章节来源**
- [TsHttpUtil.js:7-23](file://src/https/TsHttpUtil.js#L7-L23)
- [TsHttpUtil.js:28-35](file://src/https/TsHttpUtil.js#L28-L35)
### API 接口说明
#### get() 方法
**方法签名**
```javascript
async function get(url, params = {}, options = {})
```
**参数说明**
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
|-------|------|------|--------|------|
| url | string | 是 | - | 请求的URL地址 |
| params | object | 否 | {} | GET请求参数 |
| options | object | 否 | {} | 请求选项 |
**返回值**
```javascript
{
data: any, // 响应数据
recordsTotal: number // 总记录数
}
```
**使用示例**
```javascript
// 基本使用
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() 方法
**方法签名**
```javascript
async function post(url, data = {}, options = {})
```
**参数说明**
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
|-------|------|------|--------|------|
| url | string | 是 | - | 请求的URL地址 |
| data | object | 否 | {} | POST请求数据 |
| options | object | 否 | {} | 请求选项 |
**返回值**
```javascript
{
data: any, // 响应数据
recordsTotal: number // 总记录数
}
```
**使用示例**
```javascript
// 基本使用
const result = await HttpUtil.post('/api/users', {
name: '张三',
age: 25
});
// 表单数据
const result = await HttpUtil.post('/api/login', {
username: 'admin',
password: 'password'
}, {
requestType: 'form'
});
```
#### form() 方法
**方法签名**
```javascript
async function form(url, data = {}, options = {})
```
**参数说明**
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
|-------|------|------|--------|------|
| url | string | 是 | - | 请求的URL地址 |
| data | object | 否 | {} | 表单数据 |
| options | object | 否 | {} | 请求选项 |
**返回值**
```javascript
{
data: any, // 响应数据
recordsTotal: number // 总记录数
}
```
**使用示例**
```javascript
// 表单提交
const result = await HttpUtil.form('/api/upload', {
file: fileInput.files[0],
description: '文件描述'
});
```
#### req() 方法
**方法签名**
```javascript
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 | 是否返回原始响应 |
**使用示例**
```javascript
// 自定义请求
const result = await HttpUtil.req('/api/data', {
method: 'POST',
data: {key: 'value'},
headers: {'Custom-Header': 'value'}
});
```
**章节来源**
- [TsHttpUtil.js:136-165](file://src/https/TsHttpUtil.js#L136-L165)
### 集成关系
#### 与存储模块的集成
TsHttpUtil 通过存储模块管理用户认证信息:
```mermaid
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 : 使用
```
**图表来源**
- [TsHttpUtil.js:109-111](file://src/https/TsHttpUtil.js#L109-L111)
- [TsStorage.js:13-23](file://src/utils/TsStorage.js#L13-L23)
#### 与加密模块的集成
加密功能通过 TsCrypto 和 TsSM4 实现:
```mermaid
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 : 读取配置
```
**图表来源**
- [TsHttpUtil.js:82-86](file://src/https/TsHttpUtil.js#L82-L86)
- [TsCrypto.js:5-31](file://src/utils/TsCrypto.js#L5-L31)
- [TsSM4.js:96-156](file://src/utils/TsSM4.js#L96-L156)
#### 与配置模块的集成
全局配置管理:
```mermaid
classDiagram
class TsGlobalConfig {
+defaultConfig : object
+getConfig() object
+setConfig(obj) void
}
class TsHttpUtil {
+prefix : string
+httpParams : function
+onHttpError : function
}
TsHttpUtil --> TsGlobalConfig : 读取配置
TsGlobalConfig --> TsHttpUtil : 提供配置
```
**图表来源**
- [TsGlobalConfig.js:5-29](file://src/utils/TsGlobalConfig.js#L5-L29)
- [TsHttpUtil.js:100-106](file://src/https/TsHttpUtil.js#L100-L106)
**章节来源**
- [TsHttpUtil.js:100-106](file://src/https/TsHttpUtil.js#L100-L106)
- [TsGlobalConfig.js:19-29](file://src/utils/TsGlobalConfig.js#L19-L29)
## 依赖关系分析
### 外部依赖
项目的主要外部依赖包括:
| 依赖包 | 版本 | 用途 |
|-------|------|-----|
| umi-request | 1.4.0 | HTTP 客户端库 |
| base64-js | 1.5.1 | Base64 编码/解码 |
### 内部模块依赖
```mermaid
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
```
**图表来源**
- [index.js:1-16](file://index.js#L1-L16)
- [package.json:19-22](file://package.json#L19-L22)
**章节来源**
- [package.json:19-22](file://package.json#L19-L22)
- [index.js:1-16](file://index.js#L1-L16)
## 性能考虑
### 请求优化建议
1. **批量请求**: 对于多个相关的请求,考虑合并到单个请求中以减少网络开销
2. **缓存策略**: 在业务层实现适当的缓存机制,避免重复请求相同数据
3. **超时设置**: 合理设置请求超时时间,避免长时间阻塞
4. **压缩传输**: 对大体积数据考虑使用压缩算法
### 内存管理
- 及时清理不再使用的响应数据
- 避免在请求过程中创建大量临时对象
- 注意循环引用的处理
## 故障排除指南
### 常见问题及解决方案
#### 1. 认证失败
**症状**: 返回 401 状态码
**原因**: 用户令牌无效或过期
**解决方案**:
```javascript
// 检查用户令牌
const token = Storage.getUserToken();
if (!token) {
// 重新登录
redirectToLogin();
}
// 设置自定义头部
const result = await HttpUtil.get('/api/protected', {}, {
headers: {
'Authorization': `Bearer ${token}`
}
});
```
#### 2. 数据解密失败
**症状**: 解密后数据格式错误
**原因**: 加密密钥不匹配或数据损坏
**解决方案**:
```javascript
// 检查加密配置
const encryptEnabled = Storage.getEncryptBody();
if (encryptEnabled) {
// 验证密钥配置
const config = GlobalConfig.getConfig();
if (!config.base64Key) {
throw new Error('缺少加密密钥配置');
}
}
```
#### 3. 请求超时
**症状**: 请求长时间无响应
**原因**: 网络延迟或服务器负载过高
**解决方案**:
```javascript
try {
const result = await HttpUtil.get('/api/data', {}, {
timeout: 10000 // 10秒超时
});
} catch (error) {
if (error.code === 'ECONNABORTED') {
// 处理超时
showTimeoutMessage();
}
}
```
#### 4. 参数格式错误
**症状**: 返回 400 状态码
**原因**: 请求参数格式不符合服务器要求
**解决方案**:
```javascript
// 使用分页器参数
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'
}
});
```
**章节来源**
- [TsHttpUtil.js:124-127](file://src/https/TsHttpUtil.js#L124-L127)
- [TsHttpUtil.js:130-132](file://src/https/TsHttpUtil.js#L130-L132)
## 结论
HTTP 请求模块 (TsHttpUtil) 提供了一个功能完整、易于使用的网络请求封装解决方案。其主要优势包括:
1. **统一的接口设计**: 提供简洁一致的 API 接口
2. **智能参数处理**: 自动处理分页器和条件参数
3. **完善的错误处理**: 内置状态码映射和错误回调机制
4. **灵活的安全支持**: 可选的 SM4 加密传输功能
5. **良好的模块化**: 与存储、加密、配置模块的深度集成
该模块适合在企业级应用中使用,能够有效简化网络请求的处理逻辑,提高开发效率和代码质量。通过合理的配置和使用,可以满足大多数 Web 应用的网络通信需求。