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

如何在Koa2中解析multipart/form-data中的流式上传数据

在Koa2中解析multipart/form-data流式上传数据的方法

嘿,你已经在客户端用form-data发送流式文件了对吧?在Koa2这边解析这类multipart数据其实很简单,主要靠koa-body这个中间件就能搞定,我给你一步步讲清楚怎么做:

1. 先确认依赖安装

如果还没装必要的包,先执行安装命令:

npm install koa koa-router koa-body http-status fs

2. 服务端核心代码实现

下面是完整的服务端示例,包含流式解析的配置和路由处理:

const Koa = require('koa');
const Router = require('koa-router');
const HttpStatus = require('http-status');
const koaBody = require('koa-body');
const fs = require('fs');

const app = new Koa();
const router = new Router();

// 配置koa-body,开启multipart流式解析支持
app.use(koaBody({
  multipart: true, // 必须开启这个,才能解析multipart/form-data格式
  formidable: {
    // 注意:如果不想让中间件自动把文件保存到本地,就不要设置uploadDir
    // 这样就能直接拿到原始的文件可读流
    keepExtensions: true, // 保留文件的原始扩展名
    maxFileSize: 200 * 1024 * 1024, // 限制最大文件大小,这里设为200MB
    // 可选:文件开始上传时的钩子,可以在这里提前做一些处理
    onFileBegin: (name, file) => {
      console.log(`开始接收文件:${name},文件名:${file.name}`);
    }
  }
}));

// 处理文件上传的路由(对应你客户端请求的http://localhost:3456/fileStorage)
router.post('/fileStorage', async (ctx) => {
  // 1. 获取普通表单字段
  const myField = ctx.request.body.my_field;
  console.log('收到的普通字段值:', myField);

  // 2. 获取上传的文件流和信息
  const myFile = ctx.request.files.my_file;
  console.log('文件基本信息:', {
    文件名: myFile.name,
    文件大小: myFile.size,
    MIME类型: myFile.type
  });

  // 3. 处理文件流的示例:比如写入本地文件
  // 如果需要转发到其他服务,或者做其他流式处理,直接用myFile.stream即可
  const writeStream = fs.createWriteStream(`./saved_${myFile.name}`);
  await new Promise((resolve, reject) => {
    myFile.stream.pipe(writeStream);
    writeStream.on('finish', () => {
      console.log('文件写入完成');
      resolve();
    });
    writeStream.on('error', (err) => {
      console.error('文件写入失败:', err);
      reject(err);
    });
  });

  // 返回响应
  ctx.status = HttpStatus.OK;
  ctx.body = {
    message: '文件接收并处理成功',
    receivedField: myField,
    fileInfo: {
      name: myFile.name,
      size: myFile.size
    }
  };
});

// 注册路由并启动服务
app.use(router.routes()).use(router.allowedMethods());

app.listen(3456, () => {
  console.log('服务已启动,监听地址:http://localhost:3456');
});

3. 关键配置说明

  • multipart: true:这是必须的,告诉koa-body要处理multipart/form-data格式的请求
  • 不设置formidable.uploadDir:如果设置了这个参数,koa-body会自动把文件保存到指定目录,而我们要的是流式处理,所以留空就能直接拿到file.stream这个可读流
  • file.stream:这是上传文件的原始可读流,你可以用它做任何流式操作——比如转发到其他服务、写入本地、或者做实时的文件内容处理

4. 额外:把流转发到其他服务的示例

如果需要把收到的文件流直接转发到另一个服务,比如用form-data和request库,可以在路由里这样写:

const FormData = require('form-data');
const request = require('request');

// 在路由处理函数里添加这段逻辑
const myFile = ctx.request.files.my_file;
const form = new FormData();
form.append('forward_field', 'forward_value');
// 把拿到的流添加到form-data里
form.append('forward_file', myFile.stream, { filename: myFile.name });

// 转发到目标服务
await new Promise((resolve, reject) => {
  form.submit('http://目标服务的上传接口地址', (err, res) => {
    if (err) {
      console.error('转发失败:', err);
      reject(err);
    } else {
      console.log('转发成功');
      resolve(res);
    }
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:30:59