session不直接记录上传进度,需结合session识别用户、后端存储分片状态及前端查询/上报实现;后端生成uploadid并绑定session,通过redis等原子操作存储进度,前端轮询独立接口获取状态,合并前须校验分片完整性与session有效性。

Session 本身不直接记录上传进度,它只是服务端用来标识用户会话状态的机制。真正校验分片上传进度,需要结合 Session(识别用户) + 后端存储(记录每个文件的分片状态) + 前端主动查询或上报来实现。
用 Session 关联用户与上传任务
用户开始上传前,后端生成唯一任务 ID(如 uploadId),并将其与当前 Session 绑定(例如存入 Redis 或数据库,key 为 session_id:uploadId)。这样后续所有分片请求都携带该 uploadId,后端通过 Session 验证用户身份,再查对应任务状态。
- 前端在第一个分片请求中,由后端返回
uploadId,后续所有分片带上它 - 后端接口校验:先确认该 Session 是否合法(如检查 session cookie 或 token),再确认该
uploadId属于当前用户 - 避免用户伪造
uploadId:不能仅靠前端传参,必须服务端校验归属关系
服务端持久化分片接收状态
每成功接收一个分片,就更新该 uploadId 对应的进度记录。推荐使用轻量、支持原子操作的存储(如 Redis):
- 用 Hash 结构存:`upload:${uploadId}` → `{total: 100, uploaded: 23, md5s: "a,b,c..."}`
- 或用 Sorted Set 记录已上传分片序号,再用 `ZCARD` 获取已传数量
- 关键点:每次写入要保证原子性,避免并发导致计数错误;可配合 Lua 脚本或事务
前端按需查询实时进度
前端可通过轮询或长连接(如 SSE)调用独立进度接口,传入 uploadId 和 Session 凭据(如 cookie),后端返回当前完成情况:
- 接口示例:
GET /api/upload/progress?uploadId=xxx - 响应示例:
{uploaded: 42, total: 100, status: "uploading"} - 注意:不要在每个分片响应体里塞进度(增加冗余),单独接口更清晰、可缓存、易调试
合并前做最终一致性校验
当所有分片标称上传完成,触发合并前,必须再次校验:
- 检查实际存储的分片文件是否齐全(如按序号遍历是否存在)
- 比对分片哈希(如 MD5 或 SHA256)防止篡改或丢失
- 确认 Session 仍有效(未过期、未登出),避免“上传完成但用户已退出”场景
- 校验通过才执行合并,否则返回错误并提示重试
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











