Nest.js集成SAP BTP DMS下载文件写入编码异常问题求助
解决SAP BTP DMS与Nest.js集成时文件写入编码异常问题
问题核心原因是:请求中指定了接受压缩编码(Accept-Encoding: gzip, deflate, br),但代码未对服务器返回的压缩二进制数据进行解压,直接写入文件导致内容损坏。Postman会自动处理压缩响应的解压,因此下载的文件正常。
解决方案一:移除压缩请求头(最简单有效)
直接删除请求中的Accept-Encoding头,让服务器返回未压缩的原始文件数据,无需额外处理即可正常写入:
修改后的下载代码
const filesAsBinary = []; for await (const obj of objects) { const response = await firstValueFrom( this.http.get(`${sURL}/${obj}`, { headers: { Authorization: `Bearer ${sJWTTOken}`, }, responseType: 'arraybuffer', }), ); // 直接存储响应的原始二进制数据 filesAsBinary.push({ filename: obj, content: response.data }); }
写入代码调整
import * as fs from 'fs'; import * as path from 'path'; for (const file of allFilesAsBinaryFromFolder) { const filePath = path.join( 'src', 'new-accession', 'documents', `email-${folderName}`, file.filename ); // 写入二进制数据时无需指定编码,直接传入Buffer/ArrayBuffer fs.writeFileSync(filePath, file.content); }
解决方案二:保留压缩头并处理解压(若需优化传输效率)
如果必须通过压缩减少传输体积,需根据响应头的Content-Encoding对数据进行解压:
安装依赖(如需处理brotli压缩)
npm install brotli-decompress
带解压逻辑的下载代码
import * as zlib from 'zlib'; import { promisify } from 'util'; import brotliDecompress from 'brotli-decompress'; // 转换为异步方法 const gunzip = promisify(zlib.gunzip); const inflate = promisify(zlib.inflate); const brotliDecompressAsync = promisify(brotliDecompress); const filesAsBinary = []; for await (const obj of objects) { const response = await firstValueFrom( this.http.get(`${sURL}/${obj}`, { headers: { Authorization: `Bearer ${sJWTTOken}`, 'Accept-Encoding': 'gzip, deflate, br', }, responseType: 'arraybuffer', observe: 'response', // 需获取响应头信息 }), ); let rawContent = Buffer.from(response.data); const contentEncoding = response.headers['content-encoding']; // 根据压缩类型解压 if (contentEncoding) { if (contentEncoding.includes('gzip')) { rawContent = await gunzip(rawContent); } else if (contentEncoding.includes('deflate')) { rawContent = await inflate(rawContent); } else if (contentEncoding.includes('br')) { rawContent = await brotliDecompressAsync(rawContent); } } filesAsBinary.push({ filename: obj, content: rawContent }); }
写入代码同方案一
直接写入解压后的rawContent即可。
注意:写入二进制文件时,不要为
fs.writeFileSync指定任何编码参数,否则会强制将二进制数据按文本编码解析,导致文件损坏。
内容的提问来源于stack exchange,提问作者Daniel Cabral
相关产品推荐
相关产品推荐

