当前位置: 首页 > article >正文

慢速上传导致浏览器重试

触发场景Chrome 开启网络限速后Go 上传接口 20 秒超时但浏览器端一个 upload 请求 pending 约 40 秒。该博客由 AI 根据调试过程整理。触发场景项目中有一个音频上传接口mux.Handle(POST /v1/audio/upload,chain(http.HandlerFunc(audioHandler.AudioUpload),middleware.AuthMiddleware(cfg.SessionStore),middleware.LoggingMiddleware,))服务端配置了 20 秒读超时server:http.Server{Addr::80,Handler:mux,ReadTimeout:20*time.Second,WriteTimeout:20*time.Second,IdleTimeout:60*time.Second,}上传接口中通过ParseMultipartForm读取文件err:r.ParseMultipartForm(1020)iferr!nil{log.Println(fail to parse,err)response.WriteJSON(w,http.StatusBadRequest,response.Fail(response.CodeInternalError))return}在 Chrome DevTools 中开启Fast 4G限速后上传一个约 3.6 MB 的 MP3 文件服务端出现如下日志upload id: 7dc45d25-242b-4541-a4c4-75fa1b97dd0f remote: [::1]:52130 upload body read result: bytes3358720 cost19.9993135s speed164.01 KB/s errread tcp [::1]:80-[::1]:52130: i/o timeout POST /v1/audio/upload 19.9998646s upload id: 7dc45d25-242b-4541-a4c4-75fa1b97dd0f remote: [::1]:18057浏览器 Network 面板中却只看到一个upload请求并且 pending 约 40 秒。表面上看很奇怪前端只调用了一次 fetch Chrome 只显示一个 upload 服务端却看到两次 TCP 连接 每次都在 20 秒左右超时如何确认不是前端重复调用为了排除前端重复触发可以给每次上传生成一个请求 IDasyncfunctionuploadAudio(file){constdatanewFormData();data.set(file,file);constuploadIDcrypto.randomUUID();console.log(upload id,uploadID);returnrequestJSON(/v1/audio/upload,{method:POST,body:data,headers:{X-Upload-Id:uploadID,},});}后端打印请求 ID 和客户端地址log.Println(upload id:,r.Header.Get(X-Upload-Id),remote:,r.RemoteAddr)结果两次服务端日志中的X-Upload-Id完全相同但remote端口不同upload id: 7dc45d25-242b-4541-a4c4-75fa1b97dd0f remote: [::1]:52130 upload id: 7dc45d25-242b-4541-a4c4-75fa1b97dd0f remote: [::1]:18057这说明前端只发起了一次高层 fetch 请求。 浏览器底层为同一个请求建立了两次 TCP 连接。原理分析Go 的ReadTimeout不只是限制读取请求头。对于net/http.ServerReadTimeout覆盖的是连接被 accept - 读取请求头 - 读取请求体文件上传时请求体就是 multipart body。r.ParseMultipartForm(...)会持续从r.Body读取上传内容。当 Chrome 开启网络限速后服务端 20 秒内没有读完整个请求体于是触发read tcp ... i/o timeout这不是业务层正常返回失败而是服务端在读取请求体时遇到连接读超时。此时即使代码继续执行response.WriteJSON(w,http.StatusBadRequest,...)浏览器也不一定能收到一个完整、干净的 HTTP 响应。对浏览器来说这更像是底层连接异常中断。Chrome 可能会在底层重新建立连接并重试同一个请求。DevTools 仍然把它合并显示为一个upload条目所以客户端看到的是一个请求 pending 约 40 秒而服务端看到的是第一个 TCP 连接 20 秒超时 第二个 TCP 连接 20 秒超时这就是“客户端一个请求服务端两次连接”的来源。为什么 3.6 MB 也会超时服务端实际统计到的速度是bytes3358720 cost20s speed164 KB/s164 KB/s约等于1.31 Mbps。3.6 MB 文件约等于 3.65 MiB以这个速度上传需要3.65 * 1024 / 164 ≈ 22.8 秒所以 20 秒刚好不够。问题不是文件很大而是服务端把“读取完整请求体”的时间限制得太短。错误的解决方向不要把这个问题简单理解成前端重复绑定了 click 事件 gopls 启了两个 Go handler 自动执行了两次这些都不是根因。真正的问题是慢速上传时服务端 ReadTimeout 提前关闭了正在读取 body 的连接。 浏览器没有收到稳定响应底层可能重试同一个请求。解决方案方案一上传接口不要依赖全局 ReadTimeout 限制 body更推荐的服务端配置是server:http.Server{Addr::80,Handler:mux,ReadHeaderTimeout:5*time.Second,ReadTimeout:0,WriteTimeout:60*time.Second,IdleTimeout:60*time.Second,}含义是ReadHeaderTimeout限制请求头读取时间防止慢请求头攻击。 ReadTimeout: 0不使用全局读超时限制整个 body 上传。 WriteTimeout限制服务端写响应时间。 IdleTimeout限制 keep-alive 空闲连接。上传接口再单独限制请求体大小r.Bodyhttp.MaxBytesReader(w,r.Body,1020)iferr:r.ParseMultipartForm(1020);err!nil{response.WriteJSON(w,http.StatusBadRequest,response.Fail(response.CodeInternalError,fail to parse multipartform))return}这样可以把两个概念分开超大文件用 MaxBytesReader 限制大小。 慢速上传不被全局 20 秒 ReadTimeout 误杀。方案二如果只是学习项目可以调大 ReadTimeout如果暂时不想调整超时模型可以把ReadTimeout改大ReadTimeout:60*time.Second,这能解决当前 3.6 MB 文件在限速下上传失败的问题。但它不是最理想的设计因为不同用户网络差异很大文件越大越容易再次碰到类似问题。方案三客户端主动控制上传超时如果希望前端严格 20 秒后结束不等待浏览器底层重试可以用AbortControllerasyncfunctionuploadAudio(file){constdatanewFormData();data.set(file,file);constcontrollernewAbortController();consttimersetTimeout(()controller.abort(),20_000);try{returnawaitrequestJSON(/v1/audio/upload,{method:POST,body:data,signal:controller.signal,});}finally{clearTimeout(timer);}}注意客户端超时是用户体验控制不能代替服务端大小限制。生产环境的常见做法生产环境中大文件通常不直接经过业务服务器而是采用对象存储直传前端 - 后端申请上传凭证 后端 - 前端返回预签名 URL 前端 - 对象存储上传文件 前端 - 后端提交文件 metadata这样业务服务器不负责承载大文件上传流量也不会因为业务接口的读超时影响文件传输链路。最终结论这个问题的核心不是“前端调用了两次接口”而是一个 fetch 上传请求在慢速网络下没有在 Go ReadTimeout 内传完 body。 服务端读 body 超时并关闭连接。 浏览器底层可能重试同一个请求。 DevTools 合并显示为一个 upload服务端却看到两个 TCP 连接。上传接口的超时设计应该区分请求头超时用 ReadHeaderTimeout。 文件大小限制用 MaxBytesReader。 用户体验超时用前端 AbortController。 大文件传输优先考虑对象存储直传。不要用一个很短的全局ReadTimeout去限制整个上传请求体否则在限速、弱网或大文件场景下很容易出现这种“客户端一个请求服务端两次超时”的现象。

相关文章:

慢速上传导致浏览器重试

触发场景:Chrome 开启网络限速后,Go 上传接口 20 秒超时,但浏览器端一个 upload 请求 pending 约 40 秒。 该博客由 AI 根据调试过程整理。触发场景 项目中有一个音频上传接口: mux.Handle("POST /v1/audio/upload", ch…...

神经网络辅助可变形匹配滤波器在光通信中的应用

1. 神经网络辅助可变形匹配滤波器技术解析在光通信系统中,匹配滤波器作为信号检测的关键组件,其性能直接影响整个通信链路的可靠性。传统固定匹配滤波器基于理想信道假设设计,当面对实际系统中的带宽限制、大气湍流等复杂信道条件时&#xff…...

多模态融合与多任务学习在智慧农业视觉系统的实战应用

1. 项目概述与核心价值 在可控环境农业(Controlled-Environment Agriculture, CEA)里,比如我们熟悉的垂直农场、智能温室,作物生长环境是高度可控的,但随之而来的管理复杂度也呈指数级上升。传统上,一个种植…...

【2024播客降本增效终极方案】:单人团队如何用开源TTS实现月产60期高保真节目(附实测MOS分对比表)

更多请点击: https://codechina.net 第一章:AI语音合成在播客制作中的应用 AI语音合成技术正深刻重塑播客内容的生产流程,从脚本转语音、多角色配音到个性化音色定制,已实现端到端自动化与高质量听感的统一。相比传统录音方式&am…...

去偏机器学习在交通行为因果推断中的应用:从关联分析到因果效应评估

1. 项目概述:当交通研究遇上因果推断在交通工程与城市规划领域,我们常常面临一个核心挑战:如何从海量的观测数据中,剥离出某个特定因素(比如一项新政策、一种交通管控措施)对人们行为的“真实”影响&#x…...

SRC 漏洞挖掘实战|反射型 XSS 漏洞详解、复现全流程与 SRC 报告模板

反射型 XSS 是 Web 安全领域入门级高频漏洞,也是 SRC 漏洞提交中最易上手的类型之一。它无数据持久化存储、触发方式简单、测试门槛极低,是零基础网安爱好者入门漏洞挖掘的首选突破口。本文从核心原理、危害、挖掘思路、实战复现到标准报告模板全流程拆解…...

Debian Bullseye定制Live ISO避坑指南:从debootstrap到xorriso的完整流程解析

Debian Bullseye定制Live ISO避坑指南:从debootstrap到xorriso的完整流程解析当我们需要快速部署一套标准化的Debian环境时,定制Live ISO无疑是最优雅的解决方案之一。不同于传统的系统安装方式,Live ISO允许我们将预先配置好的系统环境打包成…...

Hermes Agent 总记不住你说的话?3 步治好 AI 助手的“健忘症“

你有没有这样的经历:你跟它说"每次写营销文章,记得先加载技能审核",它答应得好好的。结果下一篇写出来,你又得说一遍同样的话。它就像一个只点头不记事的实习生——每轮对话都重头来过。又或者,昨天刚刚聊完…...

Midjourney火焰生成实战手册(含17组已验证火纹Prompt+SDXL对比基准数据)

更多请点击: https://codechina.net 第一章:Midjourney火焰生成的核心原理与技术边界 Midjourney 并不原生支持“火焰生成”这一独立功能,其图像合成能力完全依赖于文本提示(prompt)对扩散模型隐空间的引导。所谓“火…...

医考app哪个比较好?2026年四款主流医考App深度横评(医路赢家/医考帮/蓝基因/丁香医考)

本文导读:市面上医考app越来越多,选错浪费时间还耽误备考。我从题库、课程覆盖、服务、通过率、核心特色、优点、缺点、适合人群八个维度,逐款拆解目前最主流的四款医考App——医路赢家、医考帮、蓝基因、丁香医考。全文无广,真实…...

两个世界的同一种崩溃:从窗口黑屏到宇宙热寂的同构联想

一、两个世界的同一种崩溃 一段着色器代码中 cell.xy 的缩放因子从 9 被修改为 99。着色器随即呈现完全黑屏——既无报错信息,也无渲染异常,只有纯粹、彻底、连噪点都不存在的黑色。在屏幕的某个抽象维度上,发生了一件与理论物理学家在黑板上…...

Linux内核性能调优实战:用ftrace揪出导致系统卡顿的369微秒元凶

Linux内核性能调优实战:用ftrace揪出导致系统卡顿的369微秒元凶当线上服务器出现偶发性性能抖动时,那种"明明有资源却跑不动"的无力感最让人抓狂。上周我们的日志集群就遇到了这样的怪事——平均延迟一切正常,但总有那么几个请求会…...

双系统硬盘告急?手把手教你用Ubuntu Live U盘和gparted无损调整/home分区大小

双系统用户必看:Ubuntu分区扩容实战指南你是否也遇到过这样的尴尬——当初安装双系统时随手给Ubuntu的分区分配空间,结果用着用着发现/home目录快被塞爆了,而根目录/却还有大量闲置空间?这种"旱的旱死,涝的涝死&q…...

别再到处找驱动了!手把手教你为ESXi 7.0 U3集成Broadcom阵列卡驱动(保姆级图文)

深度实战:为ESXi 7.0 U3定制集成Broadcom阵列卡驱动的完整指南虚拟化平台部署中最令人头疼的瞬间,莫过于当你精心准备的ESXi安装镜像在服务器上启动后,屏幕上赫然出现"No network adapter found"或"Storage controller not de…...

Windows 11系统下,Fiddler代理端口不是8888?这份Mumu模拟器网络调试避坑指南请收好

Windows 11系统下Fiddler与Mumu模拟器网络调试实战指南在移动应用开发和测试过程中,网络调试工具与模拟器的配合使用是必不可少的环节。许多开发者习惯性地认为Fiddler的默认代理端口就是8888,但在实际配置中,这个假设往往会导致一系列难以排…...

紧急预警:新课标实施倒计时90天!用PlayAI快速构建跨学科项目式学习(PBL)资源包的5步极速法

更多请点击: https://kaifayun.com 第一章:紧急预警:新课标实施倒计时90天!用PlayAI快速构建跨学科项目式学习(PBL)资源包的5步极速法 距离《义务教育课程方案(2022年版)》全面落地…...

超冷原子吸收成像的深度学习优化方法

1. 超冷原子吸收图像分析的技术挑战在超冷原子实验中,原子云的空间分布信息是理解量子态的关键指标。吸收成像技术通过测量原子云对共振激光的吸收情况,能够非破坏性地获取这一信息。典型的吸收成像过程需要采集三帧图像:包含原子的图像&…...

Vision Mamba边缘加速器设计:软硬件协同优化与混合量化策略

1. 项目概述:为什么边缘设备需要为Vision Mamba“量身定制”加速器?在边缘设备上跑视觉模型,听起来就像让一辆家用轿车去跑拉力赛。算力、内存、功耗,处处都是掣肘。传统的视觉Transformer(ViT)虽然性能强悍…...

AI驱动的高能物理探测器协同优化设计与实践

1. 高能物理探测器设计的范式转变在大型强子对撞机(LHC)时代,探测器设计面临前所未有的挑战。以CMS实验为例,其硅像素跟踪器的材料预算曾引发激烈讨论——虽然40-60%的光子转换概率有助于希格斯玻色子双光子衰变通道的识别&#x…...

事件相机预处理芯片:基于混合内存计算的图像恢复与区域提取

1. 项目概述:为事件相机打造一颗“聪明”的本地大脑如果你接触过机器人、自动驾驶或者智能监控,大概率听说过“事件相机”(Event-based Camera),或者更学术一点的名字——神经形态视觉传感器。和咱们手机里每秒拍几十张…...

Flutter+React Native如何真正实现Lovable?跨端情感一致性开发规范(仅限内部团队流通版)

更多请点击: https://codechina.net 第一章:Lovable移动端应用开发 Lovable 是一套面向现代移动开发的轻量级跨平台框架,专为构建高响应、低资源占用且具备原生体验的应用而设计。它采用声明式 UI 编程模型,底层通过桥接机制与 i…...

别再手动跑Jupyter了!Lindy标准化流程强制接管你的分析工作流(仅剩最后23个企业未迁移)

更多请点击: https://codechina.net 第一章:Lindy数据分析自动化流程的演进逻辑与核心价值 Lindy效应指出,一个事物的预期剩余寿命与其当前已存在时间成正比——在数据分析领域,这一原理映射为:越经受住多轮业务迭代、…...

焰境·万载——新一代文旅网站制作展示

江西万载数字文旅平台 北京高校在读生发起 AI 技术赋能县域文旅数字化转型 项目简介 焰境万载是围绕江西省万载县打造的数字文旅平台,以"中国花炮之乡"的千年烟花文化为核心,融合非遗传承、美食特产、旅游导览,以 AI 动漫角色&q…...

Claude + MS Project双引擎协同术:5分钟完成跨时区资源冲突检测与重排程,压测显示交付准时率提升41.6%

更多请点击: https://codechina.net 第一章:Claude项目管理应用技巧 Claude 作为具备强推理与长上下文理解能力的大语言模型,可深度融入项目管理全生命周期,提升需求分析、任务拆解、进度追踪与风险预判效率。关键在于将其定位为…...

抖音无水印视频下载实战:突破平台限制的高效内容获取方案

抖音无水印视频下载实战:突破平台限制的高效内容获取方案 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback su…...

扒了一个真实案例:这家律所凭什么稳坐AI搜索推荐位?

上周帮家里人查法律问题,用AI搜索"交通事故责任纠纷律所推荐",结果你猜怎么着——有家律所的名字出现了至少三次,每次都是高亮推荐。 这不是巧合。我顺着往下查,发现它在婚姻家事领域同样榜上有名。 我决定深挖一下&…...

免费开源AMD Ryzen调试工具:释放硬件潜能的全方位指南

免费开源AMD Ryzen调试工具:释放硬件潜能的全方位指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gi…...

【码上爬】 题十九:法外狂徒 相应数据加密还原,堆栈分析,扣代码

暗号:aHR0cHM6Ly9tYXNoYW5ncGEuY29tL3Byb2JsZW0tZGV0YWlsLzE5Lw 题目: 先对接口进行分析,参数中并没有任何加密,只是返回的数据是加密的,一个R 一个k 推测r是数据内容,k是解密密钥,进入堆栈以后…...

洛谷 B4361:[GESP202506 四级] 排序

【题目来源】 https://www.luogu.com.cn/problem/B4361 【题目描述】 体育课上有 n 名同学排成一队,从前往后数第 i 位同学的身高为 hi,体重为 wi​。目前排成的队伍看起来参差不齐,老师希望同学们能按照身高从高到低的顺序排队,…...

集团首都公报:武汉市放飞炬人产业引导基金有限责任公司财政处批准 《武汉市放飞炬人产业引导基金有限责任公司财政处现金顾问制条令》

集团首都公报:武汉市放飞炬人产业引导基金有限责任公司财政处批准 《武汉市放飞炬人产业引导基金有限责任公司财政处现金顾问制条令》...