问题描述
我正在使用Loopback 4,并且陷入了创建POST方法的困境,以便客户端可以调用此方法并上传multipart/form-data.我读了一些例子:
I'm working in Loopback 4 and getting stuck in creating a POST method so that client can call this method and upload a multipart/form-data.I read some examples:
- https://medium.com/@ jackrobertscott/upload-files-to-aws-s3-in-loopback-29a3f01119f4
- https://github.com/strongloop/loopback-example-storage
- https://medium.com/@jackrobertscott/upload-files-to-aws-s3-in-loopback-29a3f01119f4
- https://github.com/strongloop/loopback-example-storage
但是,看起来它们不适合环回4.
But, look like they are not suitable for Loopback 4.
您能帮我通过Loopback4中的POST方法上传多部分/表单数据吗?
Could you help me to upload multipart/form-data via POST method in Loopback4.
推荐答案
最近通过 https://github.com/strongloop/loopback-next/pull/1936 .
由于处理上传文件的方式有很多,因此LoopBack 4没有提供开箱即用的通用文件上传解决方案.相反,它允许应用程序实现自己的文件上传处理程序.
Because there are many different ways how to process the uploaded files, LoopBack 4 does not provide a generic file-upload solution out of the box. Instead, it allows applications to implement their own file-upload handler.
在下面的示例中,我将multer
配置为使用内存存储.这可能不是您要在生产中执行的操作,请参考 multer 文档以了解如何配置其他存储后端.
In the examples below, I am configuring multer
to use memory storage. This is probably not what you want to do in production, please refer to multer documentation to learn how to configure different storage backend.
还要注意,您也可以在TypeScript中使用multer
,只需安装&将@types/multer
添加到您的devDependencies
.
Also note that you can use multer
in TypeScript too, just install & add @types/multer
to your devDependencies
.
1.在您的控制器方法中处理文件上传
您可以告诉LoopBack跳过主体解析,并将完整请求传递给控制器方法.在控制器方法中,调用multer
来处理文件上载.完整的工作示例可以在 file-upload.acceptance.ts ,我在此处交叉发布了控制器的实现.
You can tell LoopBack to skip body parsing and pass the full request to your controller method. In the controller method, call multer
to handle file upload. A full working example can be found in file-upload.acceptance.ts, I am cross-posting the controller implementation here.
class FileUploadController {
@post('/show-body', {
responses: {
200: {
content: {
'application/json': {
schema: {
type: 'object',
},
},
},
description: '',
},
},
})
async showBody(
@requestBody({
description: 'multipart/form-data value.',
required: true,
content: {
'multipart/form-data': {
// Skip body parsing
'x-parser': 'stream',
schema: {type: 'object'},
},
},
})
request: Request,
@inject(RestBindings.Http.RESPONSE) response: Response,
): Promise<Object> {
const storage = multer.memoryStorage();
const upload = multer({storage});
return new Promise<object>((resolve, reject) => {
upload.any()(request, response, err => {
if (err) return reject(err);
resolve({
files: request.files,
fields: (request as any).fields,
});
});
});
}
}
2.注册自定义LB4 BodyParser
或者,您可以将文件上载请求的解析移至专门的正文解析器,从而简化控制器方法以接收解析的结果.当您有多个控制器方法接受文件上载时,此功能特别有用.
Alternatively, you can move parsing of file upload requests to a specialized body parser, and thus simplify your controller methods to receive the parsed result. This is especially useful when you have more than one controller method accepting file uploads.
可以在 file-upload-with-parser.acceptance.ts ,我在此处交叉发布了相关片段.
A full working example can be found in file-upload-with-parser.acceptance.ts, I am cross-posting the relevant snippets here.
解析器:
class MultipartFormDataBodyParser implements BodyParser {
name = FORM_DATA;
supports(mediaType: string) {
// The mediaType can be
// `multipart/form-data; boundary=--------------------------979177593423179356726653`
return mediaType.startsWith(FORM_DATA);
}
async parse(request: Request): Promise<RequestBody> {
const storage = multer.memoryStorage();
const upload = multer({storage});
return new Promise<RequestBody>((resolve, reject) => {
upload.any()(request, {} as any, err => {
if (err) return reject(err);
resolve({
value: {
files: request.files,
fields: (request as any).fields,
},
});
});
});
}
}
在应用程序的构造函数中注册解析器:
Parser registration in your Application's constructor:
app.bodyParser(MultipartFormDataBodyParser);
最后是控制器:
class FileUploadController {
@post('/show-body', {
responses: {
200: {
content: {
'application/json': {
schema: {
type: 'object',
},
},
},
description: '',
},
},
})
async showBody(
@requestBody({
description: 'multipart/form-data value.',
required: true,
content: {
[FORM_DATA]: {
schema: {type: 'object'},
},
},
})
body: unknown,
) {
return body;
}
}
这篇关于回送4:通过POST方法上传多部分/表单数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!