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

如何用Node.js Express保存Xero返回的原始文件内容

从Xero附件API下载文件并保存原始内容的问题

我正在集成Xero的软件中下载文件,已经获取到Xero的响应,但不知道如何保存返回的原始文件内容。参考了Xero的附件API文档后,得到的响应是乱码格式的原始内容:

\����[�����\u0012���\u0010����������="�\u001bֱ�\u0002��Kl�b��6\u0011�,�-��d\u0001�k��V�x�K�+\u0001q(\u0001\u0007NO'�]\u0018���\u0004)\u000e�\b#Ӓ��"��\u000f\u001b�=�u��\f�~%�o�K_�Me\u0005�r�F���"\u0012@�\u0003�k����\u0014\u001d�K�\u001bNK�\u0012\u0006�p0�\u001c\u0012{�\u0000���\u0012k��\u0006�\u0000)7\u0010�p1���yݗƯ�z׍o>\u0019i�<ҥ�/ښ�K\u0007�T��\u0010�4i��bzaI玼W�_X��n���(P�[\u0003�x�e\u0006�,�-�[H�v���3�<\u0006��O�eG/��ƣnǖ��=3ڼ��O�M�\u0007�>�k�߈�,����\u001bL֩\u001c�\u0012��\u0004�\u0002I��[\u0004�q���S�����.�U�-����.�j��w\u001a����\u0011��U{)Z�\u0003ׯa����+�u\u0003 �a�f�6��K�\u0007�\u0018\u0001\u0001<��\u000ekQ�6�_g��؁[\u0004���+俋�������}\u000b]׎����\u0012{]&quot;?���8m��b\u0004wjaM�D���{9����o\u0000\f��=�����\u0000\u0005��ëo��[�\n�~�?\u0013��:j�|��%��$�əT1ʌ\u001c�{�տ\u0001i��_�m��i��Xio4�V���#mt����#\u0013�\u0001�,��q�dW��U=\u0016{?��J����&�l��6G#\u0002O�\u0004\u000fz��Ӕj% >I�\u0000�M���\u0011<l.e+��&+x����6��\t��Ƿ�u\u0012Rl�8*N\u0006}?¿\u0007��&gt;7�_ÿ\u0010x��<ա�4m\u001fN�໶$����\u0012\u000f�܃¨$⾯��\u0000��|\u0012�Ԧ�/\fkw��/\u0012��r���� l�V��<�;�\u000b�?S�\u0015�ߖ�k�X\u0013Џ�s.�ѼC��\u0011'�mD�]�\u0013-�2(xf��\u0016�2�����s�\u0006�9|*���6���}P��[����d�ݾ�\u001c���\u0016\u0005��C�\u000e��tR�|0񭭢���C�\u0002\u0010s��&gt;+�\u0011q�Lg�!�&amp;�\u000f�Q�=0�C�\u0000\t\r�A�\u0004Y������p���H2�\u0019�6\u001c�\u000f�\u0000U.߲\u001a��F�;��\u0002\u000b�b�H�:\u0018������w��|9�O➩���\u001f\u000eu��R4�C\u0004\u0011]G�χ{\u001dѰ�\u000e}�\rw�(�s�@�m\u0002[çG)\fڀ\t��]ߨ��+m�4���Hw\u001ff��5�����)�\u001a��Þ\u0012��V�����m\u0003)�s\u001b�|��a�#���x\u0015���3����j𵮽m໯\u0017èI"N��c[@�\u0018�#�>\u0013'\u0019 \f�5���M&�\u0003�$���>j\u0006\

我尝试了以下代码,但没能成功保存文件:

const response: any = await xeroService.downloadFileFromUrl(attachmentUrls, resAttachment?.xeroTokenInfo);
const writer = fs.createWriteStream('image.png');

response?.data?.pipe(writer);

res.send(response.data);

解决方案

核心问题分析

Xero返回的是二进制文件内容,乱码是直接将二进制数据以字符串形式展示导致的。你的代码存在两个关键问题:

  • 未确保请求获取的是二进制数据流
  • 缺少流操作的错误处理和完成回调

修正后的代码实现

1. 确保请求返回二进制数据

如果使用Axios发起请求,需在配置中指定responseType: 'stream'或responseType: 'arraybuffer',示例:

// xeroService.downloadFileFromUrl 内部的请求配置
const config = {
  method: 'GET',
  url: attachmentUrl,
  headers: {
    'Authorization': `Bearer ${token}`
  },
  responseType: 'stream' // 关键:获取流形式的二进制数据
};

2. 正确保存流到文件

添加错误监听和完成回调,确保文件写入成功:

const response: any = await xeroService.downloadFileFromUrl(attachmentUrls, resAttachment?.xeroTokenInfo);
const writer = fs.createWriteStream('image.png');

// 处理流的错误和完成事件
response.data.pipe(writer);
writer.on('finish', () => {
  console.log('文件保存成功');
  res.send('文件已保存');
});
writer.on('error', (err) => {
  console.error('文件保存失败:', err);
  res.status(500).send('文件保存失败');
});

3. ArrayBuffer格式的替代方案

如果获取的是ArrayBuffer类型数据,可直接转为Buffer写入文件:

const buffer = Buffer.from(response.data);
fs.writeFile('image.png', buffer, (err) => {
  if (err) {
    console.error(err);
    res.status(500).send('保存失败');
  } else {
    console.log('文件保存成功');
    res.send('文件已保存');
  }
});

额外注意事项

  • 不要硬编码文件名image.png,可从响应头的Content-Type或Xero返回的附件元数据中获取正确的文件名和扩展名
  • 确保文件写入路径有足够的读写权限

内容的提问来源于stack exchange,提问作者Harpreet Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 22:58:14