.NET Core Ajax返回xlsx文件报ERR_CONNECTION_RESET问题咨询
问题修复方案
你的问题由两个独立的bug共同导致,分别出在后端和前端代码中:
1. 后端流指针位置错误
你把文件内容拷贝到MemoryStream之后,流的读取指针默认停在流的末尾,框架读取流生成响应的时候,从指针位置开始读不到任何有效内容,会直接触发连接断开,这就是浏览器报net::ERR_CONNECTION_RESET的核心原因。
修复只需要在拷贝完成后,把流指针重置到起始位置即可,修正后的后端代码:
public IActionResult ConvertToXlsx(IFormFile xlsfile) { // 简化逻辑:直接返回测试文件 var path = "wwwroot/temp/"; var filepath = Path.Combine(path, "test.xlsx"); MemoryStream ms = new MemoryStream(); using(FileStream fs = System.IO.File.OpenRead(filepath)) { fs.CopyTo(ms); } // 关键操作:将流指针重置到开头 ms.Position = 0; // 第三个参数可以指定下载时的文件名,按需传即可 return File(ms, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "converted.xlsx"); }
优化提示:你完全不需要手动把文件拷贝到MemoryStream,直接返回文件流即可,框架会自动处理流的释放:return File(System.IO.File.OpenRead(filepath), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "converted.xlsx");,内存占用会低很多。
2. 前端Ajax未配置二进制响应类型
就算后端修复了流的问题,你当前的Ajax配置也没法正确拿到xlsx文件:jQuery默认把响应当作文本解析,会把二进制内容按照UTF-8编码转码,最终拿到的是乱码数据,后续的openXLSFile方法根本无法正常处理。
需要给Ajax请求加xhrFields配置,指定响应类型为二进制Blob,修正后的前端代码:
if (files[0].type == "application/vnd.ms-excel") { console.log("XLS-File"); const formData = new FormData(); formData.append("xlsfile", files[0]); $.ajax({ url: '/Home/ConvertToXlsx', type: 'POST', cache: false, processData: false, data: formData, contentType: false, // 关键配置:指定响应为二进制Blob类型 xhrFields: { responseType: 'blob' }, beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val()); }, success: function (response) { // 此时response为标准Blob对象,可直接传入处理函数 openXLSFile(response); }, error: function () { console.log("转换请求失败"); } }); }
改完之后可以先在浏览器网络面板核对响应的Content-Length是否和本地test.xlsx文件大小一致,一致就说明后端返回正常,再确认success回调里拿到的Blob对象size和文件大小匹配,功能就能正常运行了。
内容的提问来源于stack exchange,提问作者neo_MHM
相关产品推荐
相关产品推荐

