Ajax下载文件出现损坏问题求解(.NET Core 3.1 环境)
问题原因&解决方法
核心错误点
- jQuery ajax responseType配置错误:jQuery的ajax方法不支持直接在顶层参数写
responseType: 'arraybuffer',你需要通过xhrFields配置项指定XHR对象的responseType,不然默认返回的是字符串而不是二进制数组,转Blob时编码出错就会导致文件损坏。 - Blob MIME类型拼写错误:你代码里写的
application/octetstream少了横杠,正确应为application/octet-stream。 - 变量未定义问题:原代码IE分支直接调用的
fileName变量没有提前声明,会导致下载失败。
修复后的代码
JavaScript代码修改
$(function () { $("#FileDownload").submit(function (e) { e.preventDefault(); console.log('Doing ajax submit'); $.ajax({ type: "GET", url: "/Home/DownloadFile", data: { "fileName": $("#fileName").val() }, // 重点:添加xhrFields配置指定返回类型 xhrFields: { responseType: 'blob' }, success: function (data) { var fileName = $("#fileName").val(); var blob = new Blob([data], { type: "application/octet-stream" }); var isIE = false || !!document.documentMode; if (isIE) { window.navigator.msSaveBlob(blob, fileName); } else { var url = window.URL || window.webkitURL; link = url.createObjectURL(blob); var a = $("<a />"); a.attr("download", fileName); a.attr("href", link); $("body").append(a); a[0].click(); $("body").remove(a); // 释放对象URL避免内存泄漏 window.URL.revokeObjectURL(link); } }, failure: function (response) { alert(response.responseText); }, error: function (response) { alert(response.responseText); } }); }); });
服务端可优化点(非必须,建议修改)
当前路径拼接存在路径遍历风险,修改后更安全:
public FileResult DownloadFile(string fileName) { try { // 正确使用Path.Combine处理路径分隔符 string path = Path.Combine(this.Environment.WebRootPath, "Files", fileName); // 校验路径防止越权下载其他目录文件 var basePath = Path.Combine(this.Environment.WebRootPath, "Files"); if (!Path.GetFullPath(path).StartsWith(Path.GetFullPath(basePath))) { return NotFound(); } byte[] bytes = System.IO.File.ReadAllBytes(path); return File(bytes, "application/octet-stream", fileName); } catch (Exception ex) { return NotFound(); } }
内容的提问来源于stack exchange,提问作者user1005310
相关产品推荐
相关产品推荐

