如何使用Golang实现文件上传进度监控_实时反馈上传状态


Go 语言需通过自定义 Reader 统计读取字节数、客户端轮询或 WebSocket 推送来实现上传进度反馈;服务端用 sync.Map 存储 uploadID 对应的已读/总量/完成状态,提供 /progress?id=xxx 查询接口。

Go 语言本身不直接提供上传进度回调机制,但可以通过包装 http.Request.Body,配合客户端分块上传(如使用 XMLHttpRequestfetchUpload.onprogress)+ 服务端流式读取 + 实时状态存储,实现文件上传进度的实时反馈。核心在于:**服务端边读边记、客户端定时轮询或用 WebSocket 主动推送**。

1. 服务端:自定义 Reader 记录已读字节数

关键是在解析 multipart 表单时,对每个文件的 io.Reader 做一层封装,实时统计已读数据量。

  • 使用 io.TeeReader 或自定义 Read 方法,在每次读取后更新共享的进度结构体(如用 sync.Map 存储以 uploadID 为 key 的进度)
  • 为每次上传分配唯一 ID(如 UUID),通过 URL 参数或表单字段传入,便于客户端查询
  • 示例片段:
func (p *ProgressReader) Read(b []byte) (n int, err error) {   n, err = p.R.Read(b)   p.mu.Lock()   p.read += int64(n)   p.mu.Unlock()   return }

2. 客户端:使用 XMLHttpRequest 或 fetch + onprogress

浏览器原生支持上传过程监听,无需额外库。

  • 设置 FormData 并添加文件和 uploadID 字段
  • XMLHttpRequest.upload.onprogress 获取当前上传进度(注意:这是客户端已发出的字节数,非服务端接收完成量;若需服务端确认进度,仍需后端配合)
  • 更可靠的做法是:上传开始后,启动定时器调用 /api/progress?upload_id=xxx 查询服务端记录的实际写入进度

3. 进度状态存储与查询接口

服务端需提供轻量、并发安全的进度暂存和读取能力。

  • 推荐使用 sync.Map 存储活跃上传任务(适合读多写少场景),key 为 uploadID,value 包含 totalSize(预估或客户端传入)、read(已接收字节数)、done(是否完成)等字段
  • 提供 GET 接口如 GET /progress?id=abc123,返回 JSON:{"uploaded": 1256432, "total": 5242880, "percent": 23.97}
  • 注意清理过期进度(例如上传超时或完成 5 分钟后自动删除)

4. 可选增强:WebSocket 主动推送进度

避免轮询开销,适合大文件或高实时性要求场景。

  • 客户端建立 WebSocket 连接并发送 uploadID
  • 服务端在 ProgressReader 更新时,通过对应 connection 推送进度消息
  • 需维护连接与 uploadID 的映射关系(可用 map[string][]*websocket.Conn + 读写锁)
  • 注意连接断开时的重连与状态同步逻辑


# js  # json  # go  # golang  # 浏览器  # 字节  # websocket  # 后端  # String  # 封装  # Error  # 结构体  # int  # 接口  # map  # 并发  # http  # 服务端  # 上传  # 客户端  # 自定义  # 已读  # 表单  # 这是  # 是在  # 推荐使用  # 可以通过 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: Windows如何拦截2345弹窗广告_Windows拦截2345弹窗方法【步骤】  Python如何创建带属性的XML节点  Win10 BitLocker加密教程 Win10给磁盘驱动器上锁【安全】  如何在 Laravel 中通过嵌套关联关系进行 orderBy 排序  如何解决同一段404代码在不同主机上表现不一致的问题  如何在包含多值的列中精准搜索指定演员?  如何使用Golang管理模块版本_Golanggo mod tidy与升级方法  PythonDocker高级项目部署教程_多容器管理与CI/CD流水线  如何使用Golang开发基础文件下载功能_Golang HTTP文件响应与缓存实现  Win11怎么关闭OneDrive同步_Win11取消自动备份文件【教程】  XML的“混合内容”是什么 怎么用DTD或XSD定义  Ajax提交表单PHP怎么接收_处理Ajax发送的表单数据技巧【指南】  C++如何使用std::transform批量处理容器元素?(代码示例)  Python变量绑定机制_引用模型解析【教程】  php打包exe怎么传递参数_命令行参数接收方法【解答】  c++如何获取map中所有的键_C++遍历键值对提取所有key的方法  Win11怎么解压RAR文件 Win11自带解压功能使用方法  Linux如何安装JDK11_Linux环境变量配置与Java开发环境搭建【教程】  PHP 中如何在函数内持久修改引用变量所指向的目标  c++的STL算法库find怎么用 在容器中查找指定元素【实用教程】  Windows10系统怎么查看已安装更新_Win10控制面板卸载补丁  Python集合操作技巧_高效去重解析【教程】  Win11怎么开启智能存储_Windows11存储感知自动清理文件  如何在JavaScript中动态拼接PHP的base_url与前端变量  C++如何使用std::optional?(处理可选值)  MAC怎么截图并快速编辑_MAC自带截图快捷键与标注工具使用【方法】  如何使用Golang defer优化性能_减少不必要的函数调用  Windows10电脑怎么设置虚拟内存_Win10高级系统设置性能  Linux怎么查找死循环进程_Linux系统负载分析与进程彻底结束【教程】  如何在 ACF 中正确更新嵌套多层的 Group 字段子字段  Drupal 中 HTML 链接被双重转义导致渲染异常的解决方案  Windows Defender扫描失败怎么办_安全模块损坏修复方式  Win11怎么设置应用分屏_Windows11贴靠布局Snap Layouts  Python生成器表达式内存优化_惰性计算说明【指导】  如何在Golang中使用内置函数_Golanglen append make等使用技巧  Windows怎样拦截WPS弹窗广告_Windows拦截WPS弹窗广告设置【步骤】  Win11如何开启telnet服务 Win11启用Telnet客户端【步骤】  c# 服务器GC和工作站GC的区别和设置  Win11资源管理器卡顿怎么办 Win11文件资源管理器重启技巧【优化】  Win11怎么设置默认输入法 Win11固定中文输入法【步骤】  如何使用Golang table-driven fuzz测试_多数据随机化发现缺陷  Windows音频驱动无声音原因解析_声卡驱动错误修复步骤  如何使用Golang模拟请求超时_Golang context与HTTP请求测试实践  如何使用正则表达式批量替换重复的星号-短横模式为固定字符串  c++如何使用std::bitset进行位图算法_c++ 快速查找与大规模数据排重【方法】  作用域操作符会影响性能吗_php静态调用性能分析【教程】  如何使用正则表达式精确匹配最多含一个换行符的 start-end 区段  如何在 Go 中正确反序列化多个并列的 XML 元素(而非 XML 数组)  Win11怎么恢复旧版开始菜单_通过软件还原Win10风格菜单【详解】  Win11开始菜单打不开_修复Windows 11点击开始图标无响应【教程】 

 2025-12-27

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.