【问题标题】:Loopback 4: Upload multipart/form-data via POST methodLoopback 4:通过 POST 方法上传 multipart/form-data
【发布时间】:2019-04-05 18:35:41
【问题描述】:

我正在使用 Loopback 4 并陷入创建 POST 方法,以便客户端可以调用此方法并上传 multipart/form-data。 我读了一些例子:

但是,看起来它们不适合 Loopback 4。

您能帮我通过 Loopback4 中的 POST 方法上传 multipart/form-data。

【问题讨论】:

  • 你有解决办法吗?

标签: loopbackjs strongloop loopback


【解决方案1】:

最近通过https://github.com/strongloop/loopback-next/pull/1936 向LoopBack 4 添加了对multipart/form-data 的支持。

由于处理上传文件的方式有很多种,LoopBack 4 没有提供开箱即用的通用文件上传解决方案。相反,它允许应用程序实现自己的文件上传处理程序。

在下面的示例中,我将multer 配置为使用内存存储。这可能不是您在生产中想要做的,请参阅multer 文档以了解如何配置不同的存储后端。

还请注意,您也可以在 TypeScript 中使用 multer,只需将 @types/multer 安装并添加到您的 devDependencies

1.在控制器方法中处理文件上传

您可以告诉 LoopBack 跳过正文解析并将完整请求传递给您的控制器方法。在控制器方法中,调用multer处理文件上传。一个完整的工作示例可以在file-upload.acceptance.ts 中找到,我在这里交叉发布了控制器实现。

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

或者,您可以将文件上传请求的解析移至专门的正文解析器,从而简化您的控制器方法以接收解析结果。当您有多个控制器方法接受文件上传时,这尤其有用。

可以在file-upload-with-parser.acceptance.ts 中找到完整的工作示例,我在此处交叉发布相关的 sn-ps。

解析器:

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,
          },
        });
      });
    });
  }
}

在应用程序的构造函数中注册解析器:

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;
  }
}

【讨论】:

【解决方案2】:

Loopback 4 团队正在实现此功能:https://github.com/strongloop/loopback-next/pull/1880

希望我们很快就会拥有它。

【讨论】:

猜你喜欢
  • 2022-07-29
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-27
  • 2018-03-28
  • 2016-12-14
相关资源
最近更新 更多