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

Node.js应用使用FormData上传远程图片遇TypeError问题求助

解决Node.js中用FormData上传远程图片的问题

错误原因

你直接传入result.body(Node.js的ReadableStream)到form.append时出错,是因为FormData的实现(不管是form-data库还是Node.js原生)不支持直接接收这种原始流类型,内部尝试监听流事件时找不到对应的方法,所以抛出TypeError: source.on is not a function。

而你尝试result.blob()没效果,大概率是因为没指定文件名,或者使用的FormData实现和Blob对象不兼容。


解决方案

根据你使用的FormData实现,分两种情况处理:

情况1:使用常用的form-data库(Node.js项目主流选择)

如果你的项目依赖的是form-data库(通过npm install form-data安装),可以用以下两种方式:

方式1:将远程图片转为Buffer后上传

const FormData = require('form-data');
const fetch = require('node-fetch');

async function uploadRemoteImage() {
  const form = new FormData();
  const imageUrl = '你的远程图片URL';

  // 获取远程图片响应
  const imgResponse = await fetch(imageUrl);
  if (!imgResponse.ok) throw new Error(`获取图片失败:${imgResponse.statusText}`);

  // 将响应转为Buffer
  const imgBuffer = await imgResponse.buffer();

  // 追加到FormData,必须指定文件名和内容类型
  form.append('file', imgBuffer, {
    filename: 'image.jpg', // 自定义文件名,后端靠这个识别文件
    contentType: imgResponse.headers.get('content-type') || 'image/jpeg'
  });

  // 发送上传请求,必须携带form-data生成的headers
  const uploadRes = await fetch('你的上传接口URL', {
    method: 'POST',
    body: form,
    headers: form.getHeaders()
  });

  const result = await uploadRes.json();
  console.log(result);
}

方式2:直接传入响应流上传(适合大文件)

const FormData = require('form-data');
const fetch = require('node-fetch');

async function uploadRemoteImage() {
  const form = new FormData();
  const imageUrl = '你的远程图片URL';

  const imgResponse = await fetch(imageUrl);
  if (!imgResponse.ok) throw new Error(`获取图片失败:${imgResponse.statusText}`);

  // 直接传入响应流,同样要指定文件名和内容类型
  form.append('file', imgResponse.body, {
    filename: 'image.jpg',
    contentType: imgResponse.headers.get('content-type') || 'image/jpeg'
  });

  const uploadRes = await fetch('你的上传接口URL', {
    method: 'POST',
    body: form,
    headers: form.getHeaders()
  });

  const result = await uploadRes.json();
  console.log(result);
}

情况2:使用Node.js 18+原生FormData

如果你的Node.js版本在18及以上,可以用原生的FormData(无需额外安装库),但需要将Blob转为File对象:

const { FormData } = require('node:formdata');
const fetch = require('node-fetch');

async function uploadRemoteImage() {
  const form = new FormData();
  const imageUrl = '你的远程图片URL';

  const imgResponse = await fetch(imageUrl);
  if (!imgResponse.ok) throw new Error(`获取图片失败:${imgResponse.statusText}`);

  // 获取Blob对象并转为File(必须指定文件名)
  const imgBlob = await imgResponse.blob();
  const imgFile = new File([imgBlob], 'image.jpg', {
    type: imgResponse.headers.get('content-type') || 'image/jpeg'
  });

  // 追加到FormData
  form.append('file', imgFile);

  // 发送上传请求
  const uploadRes = await fetch('你的上传接口URL', {
    method: 'POST',
    body: form
  });

  const result = await uploadRes.json();
  console.log(result);
}

关键注意事项

  • 必须指定文件名:后端需要通过文件名识别文件字段,不指定的话可能无法解析出正确的文件。
  • form-data库要带专属headers:用这个库时,必须通过form.getHeaders()生成请求头,否则后端会无法解析FormData格式。
  • 内容类型要匹配:尽量从响应头获取真实的content-type,避免后端识别文件类型出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:52:46