Angular下载C# Web API返回byte[]格式XML文件乱码问题
问题根因
你下载到的PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgi...是标准Base64编码串,解码后就是你预期的<?xml version="1.0" encoding="utf-8"?>开头的XML内容。问题出在两个环节:
- C# Web API默认将返回的
byte[]做了JSON序列化,自动转成Base64字符串返回,没有输出原始二进制流 - 前端设置
responseType: 'blob'后,实际拿到的是存储Base64文本的Blob对象,不是XML原始二进制,所以打开文件全是乱码
解决方案
二选一即可,优先选择方案1,大文件场景性能更好。
方案1:修正后端接口(推荐)
调整C# Web API返回逻辑,不要走JSON序列化,直接返回文件流:
[HttpGet("ExportToXML/{id}")] public IActionResult ExportToXML(string id) { // 替换为你从数据库读取XML字节数组的业务逻辑 byte[] xmlBytes = GetXmlBytesFromDatabase(id); // 直接输出二进制文件流,指定XML格式和编码 return File(xmlBytes, "text/xml; charset=utf-8", "acl.xml"); }
后端修正后,前端原有代码微调即可(补全编码声明、增加内存回收逻辑):
// service层保持blob响应类型即可 getExportData(id: string): Observable<Blob> { const url = this.buildUrl('/ExportToXML/' + id); return this.http.get(url, { responseType: 'blob' }); } // 组件下载逻辑 this.service.getExportData(item.Id) .subscribe((response) => { const element = document.createElement('a'); // 明确指定UTF-8编码,避免系统默认编码导致的乱码 const blob = new Blob([response], { type: 'text/xml;charset=utf-8' }); const url = URL.createObjectURL(blob); element.href = url; element.setAttribute('download', 'acl.xml'); document.body.appendChild(element); element.click(); // 清理DOM元素、释放对象URL,避免内存泄漏 document.body.removeChild(element); URL.revokeObjectURL(url); }, error => { console.log(error); });
方案2:不修改后端,前端解码Base64
如果暂时无法调整后端接口,可在前端将拿到的Base64字符串解码为二进制后再生成文件:
// service层修改响应类型为text,因为接口实际返回的是文本内容 getExportData(id: string): Observable<string> { const url = this.buildUrl('/ExportToXML/' + id); return this.http.get(url, { responseType: 'text' }); } // 组件下载逻辑 this.service.getExportData(item.Id) .subscribe((response) => { // 去除响应包裹的引号,拿到纯Base64字符串 const base64Str = response.replace(/"/g, ''); // Base64转二进制字节数组 const binaryString = atob(base64Str); const byteArray = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { byteArray[i] = binaryString.charCodeAt(i); } // 生成XML文件Blob const blob = new Blob([byteArray], { type: 'text/xml;charset=utf-8' }); const url = URL.createObjectURL(blob); const element = document.createElement('a'); element.href = url; element.setAttribute('download', 'acl.xml'); document.body.appendChild(element); element.click(); // 清理资源 document.body.removeChild(element); URL.revokeObjectURL(url); }, error => { console.log(error); });
验证标准
修改完成后下载文件,用文本编辑器打开,文件开头为<?xml version="1.0" encoding="utf-8"?>即为正常。
内容的提问来源于stack exchange,提问作者StrangerProgrammer
相关产品推荐
相关产品推荐

