← 返回题目列表

前端文件上传和下载有哪些注意点?

高频 中等 第 7 / 26 题 更新于 2026/07/28
前端网络文件上传下载分片上传

简化版

文件上传要关注格式和大小校验、进度展示、取消、失败重试、分片上传、断点续传和安全校验。下载要关注文件名、类型、鉴权、大文件流式处理和跨域头。前端校验只做体验,服务端必须再次校验。

详细版

上传常见方案:

  • 普通表单上传。
  • FormData 上传。
  • 直传对象存储。
  • 分片上传。
  • 秒传和断点续传。

注意点:

  • 前端校验大小和类型。
  • 服务端校验真实 MIME 和文件内容。
  • 显示上传进度。
  • 支持取消和重试。
  • 大文件分片并发控制。
  • 上传凭证要有过期时间和权限范围。

下载要处理文件名编码、鉴权、Blob、跨域暴露响应头等问题。

完整版教学

一、普通上传

小文件可以直接用 FormData:

const form = new FormData()
form.append('file', file)

请求时浏览器会生成 multipart/form-data。前端可以用 XMLHttpRequest 或 axios 获取上传进度。

二、大文件上传

大文件一次上传失败成本高,也容易超时。分片上传会把文件切成多个 chunk,每个 chunk 单独上传,失败时只重传失败分片。

断点续传需要服务端记录已上传分片。再次上传时,前端先查询已上传列表,只补传缺失部分。

秒传通常通过文件 hash 判断服务端是否已有相同文件。

三、下载处理

下载可以直接打开文件地址,也可以请求 Blob 后创建临时链接:

const url = URL.createObjectURL(blob)

如果需要从响应头读取文件名,跨域场景下服务端要配置 Access-Control-Expose-Headers 暴露对应 header。

四、面试追问与工程落地

面试官可能问:“只靠前端限制文件类型安全吗?”

不安全。用户可以绕过前端,甚至修改文件后缀。服务端必须校验文件内容、大小、类型,并做病毒扫描、权限校验和存储隔离。

工程中上传直传对象存储时,前端拿到的临时凭证权限要最小化,避免泄露后被滥用。

五、分片协议要有可验证的状态机

假设一个 1GB 文件按 8MB 分片,约有 1024 / 8 = 128 片;并发数设为 4,单片失败只重传 8MB,而不是从头重传 1GB。

字段作用服务端校验
uploadId标识一次上传会话绑定用户、文件和过期时间
partNumber分片序号范围与重复提交规则
partHash校验分片内容服务端重新计算或校验存储摘要
fileHash秒传/完整性参考不能替代权限和内容扫描
idempotency key安全重试同一分片只计一次

流程是初始化会话、查询已上传片、并发补传、完成合并、服务端校验整文件。浏览器计算全文件 hash 也消耗 CPU 和读取时间,大文件可使用增量 hash、Web Worker 或业务侧弱化“秒传”,不能让主线程长时间卡死。

“分片”只是数据切割;断点续传真正依赖服务端会话、幂等分片、完整性校验、过期清理和最终原子合并。

六、浏览器 API、下载和安全闭环

使用 FormData 时不要手动写 Content-Type: multipart/form-data,浏览器会自动补正确 boundary;手写后缺少 boundary,服务端可能无法解析。传统上传进度常用 XHR upload.onprogress,fetch 的上传进度能力要结合目标浏览器与流式请求支持评估。

下载 Blob 时及时释放 URL:

const objectUrl = URL.createObjectURL(blob)
link.href = objectUrl
link.download = safeFileName
link.click()
URL.revokeObjectURL(objectUrl)

1GB 文件先完整读成 Blob 可能占用大量内存,大文件更适合浏览器直接导航到带鉴权的短期下载 URL、流式保存或服务端 Range。跨源读取 Content-Disposition 必须通过 Access-Control-Expose-Headers 暴露。

服务端不能信扩展名、客户端 MIME 和 hash 声明。它要限制大小、识别真实类型、病毒扫描、隔离存储、生成安全文件名,并防止用户上传 HTML/SVG 后从可信域直接执行。

七、常见误区与追问

  • 误区:前端限制 accept 和文件后缀就安全。 用户可绕过页面且类型可伪造,服务端必须检测内容和权限。
  • 误区:FormData 要手动设置 multipart Content-Type。 浏览器需生成 boundary,手写不完整头反而会破坏解析。
  • 误区:切成分片就自动支持断点续传。 还需 uploadId、已上传查询、幂等重试、合并和过期清理协议。
  • 追问:分片越小越好吗? 小片降低重传成本,但增加请求、元数据和合并开销,需要按网络与文件大小权衡。
  • 追问:秒传为什么仍要鉴权? 服务端已有相同 hash 不代表当前用户有权引用或下载该文件。
  • 追问:Blob URL 为什么要 revoke? URL 持有 Blob 资源,长期不释放会增加内存占用。
  • 追问:大文件下载为何避免先转完整 Blob? 整体缓存在内存中可能造成峰值过高,应考虑直链、Range 或流式方案。

八、加强记忆

  1. 小文件:FormData 简单上传,浏览器自动管理 multipart boundary。
  2. 大文件:分片、有限并发、单片校验、幂等重试和断点查询。
  3. 会话完整:初始化、补片、合并、整体验证、过期清理缺一不可。
  4. 下载策略:小文件 Blob,大文件优先短期直链、Range 或流式处理。
  5. 前端清理:取消请求、恢复进度、revoke Blob URL。
  6. 服务端安全:重新校验类型、大小、内容、权限,并隔离不可信文件。