活动照片类应用的开发者现在有了一份具体的清单,用于在人满为患的场地中保持浏览器上传的稳定性。单个用户可能会在 Wi-Fi 和蜂窝网络之间切换,同时数十台设备在争夺同一个热点。本指南将展示如何防止照片在显示“上传完成”提示消息后消失,即使宾客锁定了手机或网络出现波动也是如此。

为什么普通的上传在婚礼和节日现场会失效

在办公室里,笔记本电脑连接着稳定的以太网,单个用户点击“发送”即可。但在婚礼招待会或音乐节上,同样的操作可能会引发一连串问题:宾客从仪式大厅走向停车场,路由器在数百部手机的压力下不堪重负,或者手机掉线 Wi-Fi 并回退到蜂窝网络。浏览器可能已经向服务器流式传输了每一个字节,但服务器尚未将文件提交到存储。如果 UI 在进度条达到 100% 的瞬间就宣布成功,宾客可能会删除照片,导致组织者面临文件丢失的问题。

“直接上传”的隐藏成本

一种天真的做法是将上传视为单个 HTTP POST 请求。当连接稳定时,这种方法可行;但在拥塞的网络中,每次中断都会迫使整个文件重新开始。当数十部手机同时重试时,用户会感到沮丧,且带宽会激增。将文件拆分为分块并跟踪每个部分会增加复杂性,但其回报是实现一种可预测、低开销且能在网络切换中幸存的传输方式。

构建可恢复的分块上传系统

以下是一个实用的分步指南。

1. 在任何数据离开浏览器之前生成上传 ID

在本地创建一个通用唯一识别码 (UUID),并将其作为第一个请求发送给服务器。服务器会在该 ID 下记录一个会话。如果浏览器随后因超时而重试,它会包含相同的 UUID,从而让服务器识别该会话并避免重复条目。这使得工作流具有幂等性——重复相同的请求不会产生副作用。

2. 将文件拆分为 5–10 MB 的分块

分块大小需要权衡。较小的分块(小于 1 MB)会增加 HTTP 请求的数量和相关的头部开销。非常大的分块会让任何中断都变得代价高昂,因为客户端必须重新发送一个巨大的部分。对于典型的照片和短视频,5–10 MB 可以达到平衡:每个请求完成得足够快,足以保持 UI 的响应性,同时请求数量又保持在可控范围内。

3. 限制并行上传的数量

移动浏览器可以打开许多连接,但在拥塞的 Wi-Fi 网络中,每个额外的流都会竞争有限的带宽。两个稳定的流优于八个竞争的流。使用 navigator.connection API 来检测低带宽状况并自动降低并发数。

4. 在 IndexedDB 中持久化上传状态

将上传 ID、已发送的分块列表以及任何服务器确认的偏移量存储在浏览器的 IndexedDB 中。如果页面重新加载或用户关闭了标签页,客户端可以在下次加载时恢复状态。当用户重新打开页面时,提示他们选择相同的文件;存储的元数据可以让上传从最后一个已确认的分块处恢复,而不是重新开始。

5. 检测真实的网络变化,而不仅仅是 navigator.onLine

即使连接无法使用,navigator.onLine 标志也经常报告“在线”。相反,应为每个分块设置一个短的请求超时时间(例如 5 秒)。如果发生超时,则视网络为断开。当连接恢复时,向服务器查询其已拥有的分块列表,然后仅继续上传缺失的部分。这避免了在短暂断网后发送重复数据。

6. 对重试应用带抖动的指数退避策略

当许多宾客的设备察觉到网络恢复时,它们可能会在同一时刻发起重试,从而使服务器不堪重负。指数退避(Exponential backoff)会让每次重试的等待时间比前一次更长,而抖动(Jitter)则增加了一个随机的小偏移量。两者的结合可以将重试流量分散在几秒钟内,防止突发峰值。

7. 显示分层且易于理解的反馈

一个三级状态栏可以传达文件的真实状态:

  • 已接收 (Received) – 服务器已存储所有分块,并将文件标记为完成。
  • 准备中 (Preparing) – 服务器正在生成缩略图或进行视频转码。
  • 可用 (Available) – 组织者可以查看或下载文件。

不要仅依赖颜色;请将图标与简短的文本结合使用,以便屏幕阅读器用户也能理解进度。

还有哪些可能出错的地方?

即便是设计良好的断点续传上传功能,也可能在一些边缘情况下遇到问题。

下一步需要关注什么

Web 平台正在不断演进。

核心总结

通过对每个分片进行追踪、在本地存储状态并进行智能重试的断点续传分片上传功能,可以将不稳定的活动网络转化为传输宾客照片的可靠通道。请落实上述检查清单。