ASP.NET Core分块响应时Endpoint挂起、报ERR_INCOMPLETE_CHUNKED_ENCODING如何解决
ASP.NET Core 分块传输(Chunked)实现指南
故障现象
在ASP.NET Core中尝试返回Transfer-Encoding: chunked格式的响应时出现异常:
- 浏览器请求一直处于pending状态,最终报错
ERR_INCOMPLETE_CHUNKED_ENCODING - 使用curl请求提示连接已关闭
原有错误实现代码如下:
endpoints.MapGet("/GetMessage", async context => { context.Response.Headers["Transfer-Encoding"] = "chunked"; await context.Response.WriteAsync("Hello World!"); // send the first part await context.Response.Body.FlushAsync(); // delay to simulate 'work' await Task.Delay(2000); // send the second part await context.Response.WriteAsync("Hello World!"); });
正确实现方案
核心注意点
本次需求为实现HTTP流式传输,保持响应连接打开,在音频文件片段生成后立即下发,实测得出以下注意事项:
- 无需手动设置
Transfer-Encoding响应头,ASP.NET Core会在未指定Content-Length且响应为流式输出时自动追加该头 - 无需手动执行Flush操作,直接调用
Response.Body.WriteAsync写入字节即可自动触发分块下发 - 必须设置对应资源的正确MIME类型,否则浏览器会等待全部响应体接收完成后才会触发
progress回调,无法实现流式实时下发效果
调整后服务端代码
endpoints.MapGet("/GetMessage", async context => { context.Response.Headers["Content-Type"] = "audio/aac"; var buf = System.Text.Encoding.ASCII.GetBytes("Hellow world !"); await context.Response.Body.WriteAsync(buf, 0, buf.Length); await Task.Delay(3000); await context.Response.Body.WriteAsync(buf, 0, buf.Length); });
配套前端测试代码
<html> <body> <h3>Hello word</h3> <script> let xhr = new XMLHttpRequest() xhr.onprogress = e => console.log("progress " + e.currentTarget.response) xhr.onload = e => console.log("load " + e.currentTarget.response) xhr.open("GET", "/GetMessage"); xhr.send(); </script> </body> </html>
实测效果
调整后功能运行符合预期,浏览器控制台会立即打印第一块响应内容,在全部响应接收完成后打印完整响应体。
内容的提问来源于stack exchange,提问作者watch_it_burn
相关产品推荐
相关产品推荐

