前端用Pako压缩.xlsx文件,ASP.NET Core 2.2后端解压失败求助
解决前端pako.deflate压缩.xlsx文件后ASP.NET Core后端解压失败的问题
核心问题分析
你的前端代码犯了一个关键错误:把二进制的.xlsx文件直接用JSON.stringify()序列化。xlsx是二进制格式,JSON无法正确处理二进制数据——这会导致原始文件的字节信息丢失或被篡改,后续的压缩操作本质上是在处理损坏的数据,后端自然无法正确解压还原。
另外,pako.deflate默认处理的是二进制数据(Uint8Array),而你传入的是JSON字符串,这也会导致压缩格式和后端预期不匹配。
正确的前端压缩实现
首先需要正确读取.xlsx文件的二进制内容,再进行deflate压缩,最后将压缩后的二进制数据以合适的格式(比如Base64)传给后端:
handleSaveFile = async (file) => { // 读取文件为ArrayBuffer(二进制) const arrayBuffer = await file.arrayBuffer(); // 转成pako支持的Uint8Array const uint8Data = new Uint8Array(arrayBuffer); // 执行deflate压缩,得到压缩后的Uint8Array const compressedData = pako.deflate(uint8Data); // 转成Base64字符串方便传输(也可以直接传Blob/FormData) const compressedBase64 = btoa(String.fromCharCode(...compressedData)); this.setState({ file: compressedBase64 }); }
ASP.NET Core 2.2后端解压实现
因为前端用的是纯deflate压缩(不带gzip头部),所以后端需要用DeflateStream而不是GZipStream来解压。以下是完整的解压代码示例:
using System.IO; using System.IO.Compression; using System.Text; public byte[] DeflateDecompress(string compressedBase64) { // 将Base64字符串转成字节数组 byte[] compressedBytes = Convert.FromBase64String(compressedBase64); using (var inputStream = new MemoryStream(compressedBytes)) using (var deflateStream = new DeflateStream(inputStream, CompressionMode.Decompress)) using (var outputStream = new MemoryStream()) { // 解压数据到输出流 deflateStream.CopyTo(outputStream); // 返回解压后的原始字节数组(即.xlsx文件的原始内容) return outputStream.ToArray(); } }
为什么之前用GZipStream不行?
GZipStream处理的是带gzip头部和尾部校验的压缩数据,而pako.deflate()默认输出的是纯deflate格式(没有gzip的额外头信息)。如果强行用GZipStream解压纯deflate数据,会因为找不到gzip头而抛出异常。
额外注意事项
- 如果你需要用gzip格式压缩(方便后端用
GZipStream解压),可以在前端使用pako.gzip()代替pako.deflate(),这样后端直接用GZipStream就能正常处理。 - 传输二进制数据时,用FormData或Blob比Base64更高效,Base64会增加约33%的体积,适合小文件场景。
内容的提问来源于stack exchange,提问作者Júlio Almeida
相关产品推荐
相关产品推荐

