使用Xero createInvoiceAttachmentByFileName上传S3文件后损坏求助
问题:Xero上传S3文件附件后损坏
使用Xero的createInvoiceAttachmentByFileName接口从S3预签名URL获取文件,上传为发票附件时无报错,但下载的附件损坏,无法正常打开或显示为原始Buffer数据。
可能的原因及修正方案
1. 拼写错误导致Content-Type失效
代码中mimType是拼写错误,正确应为mimeType。如果Content-Type未正确设置,Xero无法识别文件格式,会导致文件损坏。
2. 二进制数据处理不当
当Axios请求设置responseType: 'arraybuffer'时,res.data已经是ArrayBuffer类型,直接用Buffer.from(res.data)可能会默认以UTF-8编码转换,破坏二进制文件(如图片、PDF)的完整性。需指定二进制编码转换,或直接传递ArrayBuffer(取决于Xero SDK要求)。
3. Axios响应编码设置缺失
添加responseEncoding: 'binary'可确保Axios不自动编码二进制数据,避免数据失真。
修正后的代码
const downloadFileFromS3 = async (url) => { const res = await axios.get(url, { responseType: 'arraybuffer', responseEncoding: 'binary' // 确保二进制数据不被篡改 }); // 以binary编码转换为Buffer,适配Xero SDK要求 return Buffer.from(res.data, 'binary'); }; const uploadSingleAttachment = async (tenantId, invoiceId, s3Url) => { await getTokenSet(); const includeOnline = true; const idempotencyKey = uuidv4(); const parsedUrl = new URL(s3Url?.file); const pathname = parsedUrl.pathname; const fileName = pathname.substring(pathname.lastIndexOf('/') + 1); const fileBuffer = await downloadFileFromS3(s3Url?.file); const mimeType = s3Url?.mimeType; // 修正拼写错误 return await xero.accountingApi.createInvoiceAttachmentByFileName( tenantId, invoiceId, fileName, fileBuffer, includeOnline, idempotencyKey, { headers: { "Content-Type": mimeType } } ); };
额外排查点
- 验证S3预签名URL:直接访问该URL确认文件可正常打开,排除URL本身问题。
- 检查Xero SDK版本:确保使用最新版本的Xero Node SDK,旧版本可能存在二进制处理bug。
- 对比Buffer长度:上传前打印
fileBuffer.length,与原文件大小对比,确认数据未截断。
内容的提问来源于stack exchange,提问作者Anzar Ahmed
相关产品推荐
相关产品推荐

