Multer 在上传文件时损坏 UTF8 文件名

问题描述 投票:0回答:1

使用 axios http 客户端将 UTF-8 文件名的文件 POST 到 Multer 的正确方法是什么? Chrome 似乎正在为多部分/表单数据正文发送正确编码的有效负载

utf-8 nestjs multer
1个回答
18
投票

TL;博士

为 Multer 添加以下配置:

function checkFileType(req, file, cb) {
    // Update file name
    file.originalname = Buffer.from(file.originalname, 'latin1').toString(
      'utf8',
    );

    cb(null, true);
}
function createMulterOptions(): MulterOptions {
    return {
      fileFilter: checkFileType,
      limits: {
        fileSize: APPLICATION_CONSTANTS.DOCUMENTS.MAXIMUM_FILE_SIZE,
      },
    };
  }

请注意,此解决方法可能会破坏对正确遵循 RFC 规范的 curl 或其他客户端的支持

问题和解决方案的精确描述

昨天,我在利用 Busboy 和 multer 处理多部分/表单数据上传将文件发布到 Nestjs 服务时遇到问题。

查看 Chrome DevTools Network 选项卡,有效负载如下所示:

------WebKitFormBoundary5XkFkxkb2RYryGSn
Content-Disposition: form-data; name="document"; filename="PäterPän😂.pdf" 
Content-Type: application/pdf


------WebKitFormBoundary5XkFkxkb2RYryGSn--

采用与 US-ASCII 不同编码的 RFC2388 文件名应按如下方式传输:

------WebKitFormBoundary5XkFkxkb2RYryGSn
Content-Disposition: form-data; name="document"; filename="PäterPän😂.pdf" filename*=UTF-8''P%C3%A4terP%C3%A4n%F0%9F%98%82.pdf
Content-Type: application/pdf


------WebKitFormBoundary5XkFkxkb2RYryGSn--

UTF-8''...后面的部分是URI编码的UTF-8文件名。

知道这一点后,我寻找了一个关于如何强制 javascript fetch 的解决方案,后来也寻找了 axios HTTP 客户端来正确设置该值。我找不到任何解决方案。

因此解决此问题的唯一方法是强制 Multer 或 Busboy 将文件名解析为 UTF-8。如果 Multer 公开 Busboy 实例或允许提供自定义 Busboy 配置,那么事情就不会那么复杂。 然后我发现这个 Pull Request 提供了一种解决方法:https://github.com/expressjs/multer/pull/1102

然后,我按照上面 TL;DR 部分所述更改了 Multer 的 Nestjs 配置。

© www.soinside.com 2019 - 2024. All rights reserved.