使用Intuit Quickbooks NodeJS SDK上传商品图片遇Content-Length缺失错误
Quickbooks API 图片上传 Content-Length 缺失问题解决
错误6020的核心原因是请求缺少Content-Length头。由于你使用fs.createReadStream作为表单数据来源,form-data库无法自动同步计算内容长度,而qbClient.makeApiCall没有自动补全这个必填头。以下是两种解决方案:
方法1:手动计算并添加Content-Length头
通过异步方式计算表单总长度,手动添加到请求头中:
try { if (images?.length) { const image = images[0]; const imageFile = fs.createReadStream(image.rawInfo.path); const form = new FormData(); form.append('file_content_01', imageFile, { filename: image.rawInfo.filename, contentType: image.rawInfo.mimetype, }); form.append( 'file_metadata_01', JSON.stringify({ AttachableRef: [ { EntityRef: { type: 'Item', value: newQBProduct.Id }, }, ], ContentType: image.rawInfo.mimetype, FileName: image.rawInfo.filename, }), { contentType: 'application/json', filename: 'file_metadata_01', } ); // 异步计算表单内容总长度 const contentLength = await new Promise((resolve, reject) => { form.getLength((err, length) => { if (err) reject(err); else resolve(length); }); }); const imageResponse = await qbClient.makeApiCall({ url: `${process.env.QB_API_URL}/v3/company/${process.env.QB_COMPANY_ID}/upload?minorversion=70`, // 修正为文档指定的版本号 method: 'POST', headers: { ...form.getHeaders(), 'Content-Length': contentLength, // 添加Content-Length头 }, body: form, }); } } catch (error) { console.log({ ERROR_UPLOADING_IMAGE: error }); }
方法2:使用form-data原生submit方法发送请求
如果SDK的请求处理逻辑对form-data支持有限,可直接用form-data的submit方法发送请求,同时带上SDK的认证头:
try { if (images?.length) { const image = images[0]; const imageFile = fs.createReadStream(image.rawInfo.path); const form = new FormData(); form.append('file_content_01', imageFile, { filename: image.rawInfo.filename, contentType: image.rawInfo.mimetype, }); form.append( 'file_metadata_01', JSON.stringify({ AttachableRef: [ { EntityRef: { type: 'Item', value: newQBProduct.Id }, }, ], ContentType: image.rawInfo.mimetype, FileName: image.rawInfo.filename, }), { contentType: 'application/json', filename: 'file_metadata_01', } ); // 获取SDK的OAuth认证头(方法名以SDK实际提供为准) const authHeaders = await qbClient.getRequestHeaders(); // 提交表单请求 const response = await new Promise((resolve, reject) => { form.submit({ url: `${process.env.QB_API_URL}/v3/company/${process.env.QB_COMPANY_ID}/upload?minorversion=70`, headers: { ...authHeaders, ...form.getHeaders(), }, }, (err, res) => { if (err) reject(err); else { let responseData = ''; res.on('data', chunk => responseData += chunk); res.on('end', () => resolve(JSON.parse(responseData))); } }); }); } } catch (error) { console.log({ ERROR_UPLOADING_IMAGE: error }); }
额外注意事项
- 确保
image.rawInfo.path指向有效文件路径,流能正常读取; - 修正minorversion参数:你文档中指定的是70,代码里用的是69,建议保持一致避免版本兼容问题。
内容的提问来源于stack exchange,提问作者Carlos Sosa
相关产品推荐
相关产品推荐

