You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 14:42:20