Angular reportProgress配合ASP.NET Web API文件上传进度失效求助
上传进度功能失效根因及修复方案
核心问题排查
- 前端事件监听错误
当前代码仅监听了HttpEventType.DownloadProgress(服务端返回响应的下载进度),未监听上传请求的进度事件HttpEventType.UploadProgress,这是进度不显示的最直接原因。 - 服务端默认请求缓冲拦截
你使用的.NET Framework版本ASP.NET Web API默认会将完整请求体缓冲到服务器本地,全部接收完成后才会进入Controller逻辑,该机制会导致浏览器无法感知分段上传的进度,小文件场景下几乎看不到中间进度就直接完成。 - 测试场景干扰
如果本地测试用的文件小于10MB,上传速度极快,进度事件还没触发就已完成上传,会出现进度失效的假象,建议用100MB以上的大文件测试。 - 反向代理缓冲拦截:如果服务端前置了Nginx等反向代理,代理层默认开启的请求缓冲也会吞噬上传进度事件。
问题现象参考:
修复代码
前端Angular代码修正
添加上传进度事件监听分支即可:
uploadFile(files: File[]){ let formData = new FormData() formData.append('file', files[0], files[0].name) const req = new HttpRequest('POST', `${environment.serviceBaseApp}/UploadFile`, formData, { reportProgress: true }); this.http.request(req).subscribe(event => { switch (event.type) { case HttpEventType.Sent: console.log('Request sent!'); break; // 新增上传进度监听逻辑 case HttpEventType.UploadProgress: const uploadPercent = event.total ? Math.round(100 * event.loaded / event.total) : 0; console.log(`上传进度:${uploadPercent}%,已上传${Math.round(event.loaded / 1024)}KB`); break; case HttpEventType.ResponseHeader: console.log('Response header received!'); break; case HttpEventType.DownloadProgress: const kbLoaded = Math.round(event.loaded / 1024); console.log(`下载响应进度:${ kbLoaded }Kb loaded`); break; case HttpEventType.Response: console.log('😺 上传完成!', event.body); } }); }
后端ASP.NET Web API代码修正
禁用接口的请求缓冲即可:
public class RecepcionController : ApiController { [HttpPost] [Route("api/UploadFile")] public HttpResponseMessage UploadFiles() { // 禁用请求缓冲,保证上传进度可以正常上报 var bufferlessStream = HttpContext.Current.Request.GetBufferlessInputStream(disableMaxRequestLength: true); string path = HttpContext.Current.Server.MapPath("~/Uploads/"); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } HttpPostedFile postedFile = HttpContext.Current.Request.Files[0]; string fileName = Path.GetFileName(postedFile.FileName); postedFile.SaveAs(path + fileName); return Request.CreateResponse(HttpStatusCode.OK, fileName); } }
如果使用了Nginx反向代理,需要在对应站点配置中添加:
proxy_request_buffering off;
内容的提问来源于stack exchange,提问作者Aetos2501
相关产品推荐
相关产品推荐

