问题:
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;)
综上,希望有大神可以帮我解惑
看egg里面别人提的issue自己来回答一下
egg中ctx.getFileStream()
是对mutipart的封装,只适用于一些特定的情况:
上面提的两种情况可以解释我遇到的两个问题(怪自己没好好看) 那么改正后的服务端代码应该如下:
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 这个就很头疼 … 楼主是怎么搞得呀 ?