# 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 应用的网络通信需求。