本地存储与会话
移动端 SecureStore、缓存、文件上传、退出登录清理和离线体验
移动端会保存一些本地信息:session、用户偏好、最近请求结果。记住一句话——敏感凭据放安全存储,业务真相以后端为准。
你将学到
- SecureStore 和 AsyncStorage 分别适合存什么、不适合存什么
- 文件上传时移动端只负责哪些环节
- 退出登录时需要清理哪些本地数据、从哪些入口触发
- 弱网和离线场景的基本处理方式
本地存储选择
移动端有两种主要的本地存储,用途完全不同:
| 存储方式 | 适合放 | 不适合放 |
|---|---|---|
| SecureStore | session token、敏感凭据 | 大量列表数据、图片缓存 |
| AsyncStorage | 用户偏好、UI 状态、短期缓存 | 密钥、支付信息、数据库连接 |
实际操作中,session 和登录状态必须用 SecureStore。用户偏好(比如语言选择、主题、排序方式)可以放 AsyncStorage。短期的列表缓存也可以放 AsyncStorage,但记住它只是加速显示,不是数据来源。
不要把 AsyncStorage 当成数据库用。它适合存几 KB 的配置信息,不适合存几百条列表数据。列表数据应该每次都从 API 获取,缓存在 TanStack Query 里。
数据库连接字符串、支付服务端密钥、邮件服务密钥等敏感信息永远不要放进 App 本地存储。这些只属于服务端。
文件上传
移动端可以选图片、文件、音频或视频,但存储服务别直接暴露给 App。正确做法是:App 选文件,后端签名或转发,存储服务保存。
上传链路:
- 选择文件 -- 用户从相册或文件系统选取
- App 预处理 -- 检查大小、类型,必要时压缩
- 后端授权 -- 后端签发上传凭证或校验权限
- 对象存储 -- 上传到 R2、S3 或其他服务
移动端只关心这些环节:
| 事项 | 移动端处理 |
|---|---|
| 文件大小 | 上传前提示和限制,大文件要做压缩或分片 |
| 文件类型 | 只允许产品需要的类型,不要开放所有格式 |
| 上传进度 | 展示进行中状态,支持取消 |
| 上传失败 | 保留状态,可重试,不丢用户选择的文件 |
| 上传后预览 | 展示后端返回的可访问地址 |
| 权限 | 未登录不能上传受保护文件 |
存储密钥不能进入 App,签名或校验必须由后端完成。移动端不要直接和 R2、S3 等对象存储通信。
如果产品涉及图片上传,建议在 App 端做基础压缩:控制分辨率和质量,避免用户上传 10MB 的原图。压缩逻辑放在选择文件之后、上传之前。
退出登录要清理什么
退出登录时,确保以下内容被清理或重新拉取,避免上一个用户的数据残留在设备上:
| 类型 | 处理方式 |
|---|---|
| session | 清理 SecureStore 中的登录状态 |
| 用户资料缓存 | 清理或重新拉取 |
| 会员状态 | 清理或重新拉取 |
| 业务列表 | 退出后不继续展示上一位用户的数据 |
| 本地草稿 | 清理或标记为未关联用户 |
退出登录的清理逻辑要覆盖所有入口:
- 手动退出 -- 用户主动点击退出按钮
- token 过期 -- 服务端返回 401,本地 session 失效
- 被服务端踢出 -- 管理员操作或安全策略触发
任何一种情况发生后,用户都不应该看到残留的旧数据。建议把退出登录的清理逻辑封装成一个函数,所有入口都调用它,避免遗漏。
弱网和离线
模板不默认做完整离线数据库。第一版只要做到三点:
- 弱网时给出可理解的提示,不要让用户盯着无响应的界面
- 请求失败时保留用户输入,提供重试入口
- 不会把旧缓存当作最新数据展示
如果后续需要离线能力,优先考虑关键列表的只读缓存,而不是完整的双向同步。离线编辑的冲突处理成本很高,MVP 阶段不建议做。
存储相关的常见坑
做本地存储时,有几个地方容易踩坑:
缓存和 UI 不同步 -- 退出登录后 UI 还在显示旧用户的头像和名字。清理缓存时,确保所有依赖缓存的组件都会重新渲染。
文件路径变化 -- 不同版本的系统对文件沙箱的处理可能不同。不要把文件绝对路径存到数据库或缓存里,优先用后端返回的 URL。
SecureStore 容量限制 -- SecureStore 适合存 token 这样的小数据,不适合存大段 JSON。如果需要存复杂结构,拆成多个 key 或用 AsyncStorage。
下一步
本地存储搞清楚后,进入 数据与同步 了解 App 如何通过 API 获取数据和处理多端同步。
想和其他创造者交流?
这篇文档有问题?