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