8

What is the proper way to POST a file with a UTF-8 filename to Multer using the axios http client? Chrome seems to be sending a correctly encoded payload for the multipart/form-data body

Marc Kornberger
  • 251
  • 2
  • 7

1 Answers1

17

TL;DR

add the following configuration for Multer:

function checkFileType(req, file, cb) {
    // Update file name
    file.originalname = Buffer.from(file.originalname, 'latin1').toString(
      'utf8',
    );
}
function createMulterOptions(): MulterOptions {
    return {
      fileFilter: checkFileType,
      limits: {
        fileSize: APPLICATION_CONSTANTS.DOCUMENTS.MAXIMUM_FILE_SIZE,
      },
    };
  }

Beware this workaround might break support for curl or other clients following the RFC Spec correctly

Precise Description of Issue and Solution

Yesterday I encountered a problem while posting files to a Nestjs Service utilizing busboy and multer for handling multipart/form-data uploads.

Viewing the Chrome DevTools Network Tab the payload looked like this:

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


------WebKitFormBoundary5XkFkxkb2RYryGSn--

Following RFC2388 filenames in a different encoding than US-ASCII should be transmitted as follows:

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

The part after UTF-8''... is the URI encoded UTF-8 Filename.

Knowing this I looked for a solution on how to force javascript fetch and later also the axios HTTP Client to set this value correctly. I couldn't find any solutions.

So the only way to fix this issue was to force Multer or Busboy to parse the filename as UTF-8. This would not have been all that complicated if Multer exposed the Busboy instance or allowed for providing a custom Busboy configuration. I then discovered this Pull Request providing a workaround: https://github.com/expressjs/multer/pull/1102

I then changed my Nestjs configuration for Multer as described above in the TL;DR section.

Marc Kornberger
  • 251
  • 2
  • 7