我想在这个级别上创建一个 Nestjs 的拦截器,并且想要上传文件。我找不到解决方案,如何通过 Observable 解决此代码(https://github.com/fastify/fastify-multipart)
我正在使用 fromPromise 但使用此工具,我遇到了更多问题。因为我只能解决一次。我需要对每个文件进行验证,如果验证返回解析,则运行泵进行写入。
const mp = req.multipart(handler, function (err) {
console.log('upload completed')
reply.code(200).send()
})
// handler wil run for each file
function handler (field, file, filename, encoding, mimetype) {
// to accumulate the file in memory! Be careful!
//
// file.pipe(concat(function (buf) {
// console.log('received', filename, 'size', buf.length)
// }))
//
// or
pump(file, fs.createWriteStream('a-destination'))
// be careful of permission issues on disk and not overwrite
// sensitive files that could cause security risks
}
我使用这个代码,对于我的旧案例来说就足够了......
const obs1$ = fromPromise(new Promise((res, rej) => {
const mp = request.multipart((field, file, filename, encoding, mimetype) => {
const writeStream = fs.createWriteStream('path');
//here need run onValidation
pump(file, writeStream);
}, (err) => {
//doSuccess
(err) ? rej(err) : res();
});
}));
return obs1$.pipe(
catchError(error => {
throw new BadRequestException(error);
}),
switchMap(() => {
request.body = body;
return next.handle();
}), mergeAll());
但我有一个新案例(我需要在保存文件之前进行验证),案例是:next.hander() 使用一些方法返回 Observable:
@Controller('test')
export class TestCtrl {
@Post('upload')
@UseInterceptors(new FileInterceptor())
uploadFile() {
return {
onValidate: (file: IFiles) => {
console.log(this.tst);
return Promise.resolve(true);
},
onSuccess: () => {
return Promise.resolve(true);
}
};
}
}
尝试过这样的事情:
@Injectable()
export class FileInterceptor implements NestInterceptor {
intercept(context: any, next: CallHandler): Observable<any> {
const request = context.getRequest();
const body: Array<any> = [];
return next.handle().pipe(switchMap((methods: any) => {
const mp = request.multipart((field, file, filename, encoding, mimetype) => {
const writeStream = fs.createWriteStream('path');
body.push({
filename, file
});
methods.onValidation(file).then(() => {
pump(file, writeStream);
}).catch(() => {
writeStream.destroy();
});
}, () => {
//done
methods.onSuccess(body); // how to return this?
});
return null; // ???
}));
}
}