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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 14:00:35