egg form-data提交如果没有文件报错 cant found upload file
发布于 6 年前 作者 dogLin 4490 次浏览 来自 问答

问题: 1.如果使用mutipart/formdata提交表单,表单如果没有文件的话,egg中ctx.getFileStream()会报错cant found upload file,那这样就无法获得stream对象,就无法获取其它的字段。怎么解决?(那个因为前端那边的需求是传文件和字段,文件是可以不提交的) 2.前端使用的是Angular4写的,用的FormData对象提交文件和字段,为什么egg中ctx.getFileStream()获得的stream中fields字段是空的。

请求的截图 问题2中前端的代码

sendplayRequest() {
  let formData: FormData = new FormData();
  if(this.playRequest.file){
  	formData.append("file",this.playRequest.file)
  }
  formData.set("MsgTitle",this.playRequest.MsgTitle)
  this.apiService.PlayRequest(formData).subscribe(res => {
  console.log(res);
  })
}

PlayRequest(formData: FormData){
  return this.http
  .post(this.host + "/play",formData)
  .map(res => res.json());
}

发出的请求头

服务端代码:

const config = ctx.app.config;
//获取上传的表单文件流以及表单字段
let stream;
try{
  stream = await ctx.getFileStream();
}catch(e) {
  console.log(e);
  return await next()
}
console.log(stream.fields;)

综上,希望有大神可以帮我解惑

2 回复

看egg里面别人提的issue自己来回答一下

egg中ctx.getFileStream()是对mutipart的封装,只适用于一些特定的情况: egg官网中的说明

上面提的两种情况可以解释我遇到的两个问题(怪自己没好好看) 那么改正后的服务端代码应该如下:

var path = require("path")
var fs = require("fs")
const sendToWormhole = require("stream-wormhole");
async play() {
        const { logger, app, ctx, config } = this
        const helper = ctx.helper;
		// { autoFields: true } 可以将除了文件的其它字段提取到parts的filed中,
        const parts = this.ctx.multipart({ autoFields: true }); 
        const files = [];
        let stream;
        while ((stream = await parts()) != null) {
                const filename = stream.filename;
                const target = path.join(this.config.baseDir, 'app/public', filename);
                fs.writeFileSync(target)
                //生成写入流
                const writeStream = fs.createWriteStream(target);
                try {
                    stream.pipe(writeStream);
                } catch (err) {
                    await sendToWormhole(stream);
                    throw err;
                }
                files.push(filename);

        }

        console.log(parts.field)
        ctx.body = {
            fields: parts.field
            files,
        };
    }

这样就可以不用按照特定顺序提交参数,且文件可有可无

@dogLin egg 使用formdata的数据是怎么接受的呀 ? 我再ctx.params.body中就找不到参数 ,同时我又要在middleware中验证表单中传的token字段, 如果用formidable 搞得话,egg会直接返回404 这个就很头疼 … 楼主是怎么搞得呀 ?

回到顶部