Files
npm-tool/.qoder/repowiki/zh/content/核心模块/存储模块 (TsStorage).md

20 KiB
Raw Permalink Blame History

存储模块 (TsStorage)

**本文引用的文件列表** - [TsStorage.js](file://src/utils/TsStorage.js) - [TsCrypto.js](file://src/utils/TsCrypto.js) - [TsSM4.js](file://src/utils/TsSM4.js) - [TsCommon.js](file://src/utils/TsCommon.js) - [TsGlobalConfig.js](file://src/utils/TsGlobalConfig.js) - [TsHttpUtil.js](file://src/https/TsHttpUtil.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. 结论
  10. 附录

简介

本文件为存储模块TsStorage的完整数据持久化文档聚焦于基于浏览器 localStorage 的数据存储机制,涵盖以下主题:

  • 数据序列化与反序列化流程
  • 用户 token 管理
  • 加密开关控制与数据生命周期管理
  • 与加密模块SM4/加密器)的集成关系
  • 数据安全传输与存储最佳实践
  • 完整 API 接口说明(保存、获取、删除等)
  • 使用示例、数据迁移策略与备份恢复方案
  • 浏览器兼容性与存储容量限制

项目结构

该工具包采用“按功能域分层”的组织方式,存储模块位于 utils 目录下,并通过 index.js 汇总导出,供上层业务统一调用。

graph TB
subgraph "工具包入口"
IDX["index.js"]
end
subgraph "存储层"
TS["TsStorage.js"]
TC["TsCommon.js"]
end
subgraph "加密层"
TG["TsGlobalConfig.js"]
TSM["TsSM4.js"]
TCR["TsCrypto.js"]
end
subgraph "网络层"
TH["TsHttpUtil.js"]
end
IDX --> TS
IDX --> TCR
IDX --> TSM
IDX --> TG
IDX --> TH
TH --> TS
TH --> TCR
TH --> TG
TS --> TC
TCR --> TSM
TCR --> TG

图表来源

章节来源

核心组件

  • 存储模块TsStorage封装 localStorage 的读写、token 管理、加密开关管理,提供统一的键值存取接口。
  • 加密模块TsCrypto + TsSM4基于 SM4 算法的加解密实现,支持 ECB 模式与 Base64 输出。
  • 全局配置TsGlobalConfig提供 base64Key、前缀、HTTP 参数注入与错误回调等全局配置。
  • 通用工具TsCommon提供 JSON 解析、空值判断等基础能力。
  • 网络工具TsHttpUtil在请求中自动注入 token 与加密开关,对响应进行解密与解析。

章节来源

架构总览

存储模块与加密模块的交互路径如下:网络层在发送请求时根据加密开关对请求体进行加密;接收响应时若标记为加密,则进行解密并解析 JSON存储层负责持久化 token 与加密开关状态。

sequenceDiagram
participant App as "应用"
participant Http as "TsHttpUtil"
participant Store as "TsStorage"
participant Crypto as "TsCrypto"
participant SM4 as "TsSM4"
participant Srv as "后端服务"
App->>Store : "saveUserToken(token)"
App->>Store : "saveEncryptBody(true/false)"
App->>Http : "post(url, data)"
Http->>Store : "getEncryptBody()"
alt "加密开启"
Http->>Crypto : "encrypt(JSON.stringify(data))"
Crypto->>SM4 : "encrypt(明文)"
SM4-->>Crypto : "密文(Base64)"
Crypto-->>Http : "密文"
Http->>Srv : "POST { encryptData : 密文 }"
else "加密关闭"
Http->>Srv : "POST 原始 JSON"
end
Srv-->>Http : "响应(可能含 encrypt 标记)"
alt "响应需解密"
Http->>Crypto : "decrypt(密文)"
Crypto->>SM4 : "decrypt(密文)"
SM4-->>Crypto : "明文"
Crypto-->>Http : "明文"
Http->>Http : "parseJSON(明文)"
end
Http-->>App : "{ data, recordsTotal }"

图表来源

详细组件分析

存储模块TsStorage

  • 功能职责
    • 统一的键值存取:将任意值序列化为 JSON 字符串后写入 localStorage。
    • 用户 token 管理:提供保存与读取 token 的便捷方法。
    • 加密开关管理:保存/读取“是否对请求体进行加密”的布尔标志。
    • 安全反序列化:通过通用工具解析 JSON避免异常导致崩溃。
  • 关键实现要点
    • 写入:以 {data: value} 的结构写入 localStorage便于后续统一解析。
    • 读取:从 localStorage 读取字符串,交由通用工具解析为对象,再取出 data 字段;未命中或解析失败时返回默认值。
    • token 与加密开关:分别以固定键名保存,便于网络层直接读取。
  • 错误处理
    • 读取失败或 JSON 解析异常时,返回默认值,保证健壮性。
  • 性能与复杂度
    • 写入/读取均为 O(1),序列化/反序列化为 O(n)n 为字符串长度)。
  • 使用建议
    • 对大对象建议在上层进行拆分或压缩,避免 localStorage 膨胀。
    • 避免存储敏感信息(如明文密码),优先使用加密开关与服务端保护。
flowchart TD
Start(["函数入口"]) --> SaveGet{"save 或 get?"}
SaveGet --> |save| Serialize["JSON.stringify({data: value})"]
Serialize --> Write["localStorage.setItem(key, 字符串)"]
SaveGet --> |get| Read["localStorage.getItem(key)"]
Read --> Parse["Common.parseJSON(字符串, {data: 默认值})"]
Parse --> Extract["取 data 字段"]
Extract --> End(["返回结果"])

图表来源

章节来源

加密模块TsCrypto + TsSM4

  • 功能职责
    • 提供 SM4 加密与解密能力,支持 ECB 模式与 Base64 输出。
    • 通过全局配置注入密钥base64 编码),确保前后端一致。
  • 关键实现要点
    • 初始化:从全局配置读取 base64Key 并转换为字节数组作为密钥。
    • 模式与输出:默认 ECB 模式与 Base64 输出,满足前端直传需求。
    • 块处理:按 16 字节块进行填充、轮密钥变换与输出转换。
  • 安全性
    • ECB 模式适合小数据块加密,但不提供完整性校验;建议仅用于请求体加密场景。
    • 密钥来源于全局配置,需确保其安全性与一致性。
  • 性能与复杂度
    • 单次加/解密为 O(n)n 为数据长度),块大小固定为 16 字节。
  • 使用建议
    • 对大文本建议分片处理,避免一次性内存压力。
    • 与网络层配合使用,避免在本地重复加密。
classDiagram
class TsCrypto {
+constructor()
+encrypt(content) string
+decrypt(base64) string
-sm4 : TsSM4
}
class TsSM4 {
+constructor(config)
+encrypt(plaintext) string
+decrypt(ciphertext) string
-mode : string
-cipherType : string
-key : Uint8Array
-iv : Uint8Array
-encryptRoundKeys : Uint32Array
-decryptRoundKeys : Uint32Array
}
TsCrypto --> TsSM4 : "组合"

图表来源

章节来源

网络层与存储/加密集成TsHttpUtil

  • 功能职责
    • 在请求前根据加密开关对请求体进行加密,并替换为 { encryptData: 密文 }。
    • 在响应后根据响应标记进行解密,并解析 JSON。
    • 自动注入 token 到请求头。
  • 关键流程
    • 请求前处理:读取加密开关,若开启则对 data 进行加密;读取 token 注入到 headers。
    • 响应后处理:若响应标记为加密,则解密并解析 JSON否则直接返回 data。
  • 错误处理
    • 统一错误处理器返回标准化错误对象。
  • 性能与复杂度
    • 主要开销在 JSON 序列化/反序列化与 SM4 加解密,整体为 O(n)。
  • 使用建议
    • 通过全局配置统一设置加密开关与密钥,避免分散配置。
sequenceDiagram
participant C as "调用方"
participant H as "TsHttpUtil"
participant S as "TsStorage"
participant E as "TsCrypto"
participant M as "TsSM4"
participant R as "后端"
C->>H : "post(url, {data})"
H->>S : "getEncryptBody()"
alt "加密开启"
H->>E : "encrypt(JSON.stringify(data))"
E->>M : "encrypt(明文)"
M-->>E : "密文"
E-->>H : "密文"
H->>R : "POST { encryptData : 密文 }"
else "加密关闭"
H->>R : "POST { data }"
end
R-->>H : "响应(可能含 encrypt 标记)"
alt "响应需解密"
H->>E : "decrypt(密文)"
E->>M : "decrypt(密文)"
M-->>E : "明文"
E-->>H : "明文"
H->>H : "parseJSON(明文)"
end
H-->>C : "{ data, recordsTotal }"

图表来源

章节来源

API 接口文档(存储模块)

  • 保存用户 token
    • 方法saveUserToken(token)
    • 作用:将 token 以固定键名保存至 localStorage
    • 返回:无
    • 参考:TsStorage.js:9-11
  • 获取用户 token
    • 方法getUserToken()
    • 作用:从 localStorage 读取 token未命中返回空字符串
    • 返回:字符串
    • 参考:TsStorage.js:13-15
  • 开启/关闭请求体加密
    • 方法saveEncryptBody(bool)
    • 作用:保存布尔值以控制请求体是否加密
    • 返回:无
    • 参考:TsStorage.js:17-19
  • 读取加密开关
    • 方法getEncryptBody()
    • 作用:读取加密开关,未命中返回默认 true
    • 返回:布尔值
    • 参考:TsStorage.js:21-23
  • 通用保存
    • 方法save(key, value)
    • 作用:将任意值序列化后保存至 localStorage
    • 返回:无
    • 参考:TsStorage.js:31-33
  • 通用获取
    • 方法get(key, def)
    • 作用:从 localStorage 读取并解析 JSON返回 data 字段
    • 返回:任意类型(默认值为传入 def
    • 参考:TsStorage.js:41-43

章节来源

数据序列化与反序列化

  • 序列化
    • 将任意值包装为 {data: value},再通过 JSON.stringify 转为字符串,写入 localStorage。
    • 优点:统一结构,便于后续解析;可扩展字段(如版本号)。
    • 参考:TsStorage.js:31-33
  • 反序列化
    • 从 localStorage 读取字符串,使用通用工具解析为对象,取 data 字段作为实际值。
    • 若解析失败或未命中返回默认值def
    • 参考:TsStorage.js:41-43, TsCommon.js:34-44

章节来源

用户 token 管理

  • 存储位置:固定键名为 token
  • 读写接口saveUserToken/getUserToken
  • 使用场景:网络层在请求头中注入 token实现鉴权
  • 参考:TsStorage.js:9-15, TsHttpUtil.js:109-111

章节来源

加密开关控制与数据生命周期

  • 加密开关
  • 生命周期
    • 保存saveEncryptBody(bool)
    • 读取getEncryptBody(),未命中返回 true
    • 删除localStorage.removeItem("encrypt_body")
    • 参考:TsStorage.js:17-23

章节来源

存储模块与加密模块的集成关系

章节来源

数据安全传输与存储最佳实践

  • 传输安全
    • 使用加密开关对请求体进行加密,避免明文在网络中传输。
    • 仅对必要字段加密,避免过度加密影响性能。
    • 参考:TsHttpUtil.js:80-91
  • 存储安全
    • 不在 localStorage 中存储敏感明文(如密码、私钥)。
    • 使用加密开关保护本地缓存的敏感数据。
    • 参考:TsStorage.js:31-43
  • 配置安全

章节来源

使用示例

章节来源

数据迁移策略与备份恢复

  • 迁移策略
    • 版本升级时,可在存储层增加版本字段,读取时进行兼容性处理。
    • 对历史数据进行批量重写(如重新序列化),确保新结构可用。
    • 参考:TsStorage.js:31-43
  • 备份与恢复
    • 备份:读取所有键值并导出为 JSON 文件。
    • 恢复:导入 JSON 后逐条写入 localStorage。
    • 注意:避免在恢复过程中覆盖当前用户数据,建议先导入到临时键名,再合并。
    • 参考:TsStorage.js:31-43

章节来源

浏览器兼容性与存储容量限制

  • 浏览器兼容性
    • localStorage 在现代浏览器中广泛支持;在无痕模式或受限环境下可能不可用。
    • 参考:TsStorage.js:31-43
  • 存储容量限制
    • localStorage 通常为 510 MB因浏览器而异超出会抛出异常。
    • 建议:对大对象进行分片或压缩,避免频繁写入导致溢出。
    • 参考:TsStorage.js:31-43

章节来源

依赖关系分析

  • 模块耦合
    • TsHttpUtil 依赖 TsStorage、TsCrypto、TsGlobalConfig形成“网络层-存储层-加密层-配置层”的链路。
    • TsStorage 依赖 TsCommon用于安全解析 JSON。
    • TsCrypto 依赖 TsSM4 与全局配置,提供加解密能力。
  • 外部依赖
    • base64-jsBase64 编解码与字节数组互转。
    • umi-requestHTTP 请求封装与错误处理。
  • 可能的循环依赖
    • 当前模块间无循环依赖,结构清晰。
graph LR
Http["TsHttpUtil"] --> Store["TsStorage"]
Http --> Crypto["TsCrypto"]
Http --> Global["TsGlobalConfig"]
Store --> Common["TsCommon"]
Crypto --> SM4["TsSM4"]
Crypto --> Global

图表来源

章节来源

性能考量

  • 序列化/反序列化成本O(n)n 为字符串长度;建议对大对象进行分片或压缩。
  • 加解密成本SM4 单次加/解密 O(n),注意避免对频繁小数据进行重复加密。
  • I/O 成本localStorage 读写为 O(1),但频繁写入可能导致主线程阻塞,建议批量写入或延迟写入。
  • 建议:在业务层对热点数据进行缓存,减少重复序列化与写入。

故障排查指南

章节来源

结论

TsStorage 通过统一的序列化/反序列化与键值管理,为应用提供了简洁可靠的本地存储能力;结合加密模块与网络层,实现了从传输到存储的端到端安全方案。建议在生产环境中:

  • 明确敏感数据边界,合理启用加密开关;
  • 控制存储体积,避免 localStorage 溢出;
  • 在升级时做好版本兼容与迁移策略;
  • 严格管理密钥与配置,确保一致性与安全性。

附录

  • 入口导出
    • index.js 汇总导出各模块,便于统一引入。
    • 参考:index.js:8-15
  • 依赖清单

章节来源