Multer

repository·main·Indexed 11 days ago

https://github.com/expressjs/multer

Node.js middleware for handling `multipart/form-data`, primarily used for file uploads in Express applications. Built on top of `busboy`, version 2.2.0 provides methods like `.single()`, `.array()`, and `.fields()` to populate `req.body`, `req.file`, and `req.files`. It includes support for `DiskStorage`, `MemoryStorage`, custom storage engines, and `fileFilter` for file validation, as well as configurable `limits` to protect against DoS attacks.

Tokens
20.5K
Snippets
73
Records
94
Agent score
85%

What's inside Multer

  1. What is Multer and when to use it

    main

    Multer is middleware for the Express framework designed to handle multipart/form-data. It is primarily used for uploading files. It is built as a wrapper around busboy for maximum efficiency.

    IMPORTANT: Multer does not handle any form types other than multipart/form-data.

  2. Understand the File object properties

    main

    When a file is uploaded, Multer populates a file object with metadata. The available properties depend on the storage engine used:

    Common properties (all engines):

    • fieldname: The name of the form field.
    • originalname: The name of the file on the user's computer.
    • encoding: The file's encoding type.
    • mimetype: The MIME type of the file.
    • size: The file size in bytes.

    DiskStorage specific properties:

    • destination: The folder where the file was saved.
    • filename: The name of the file within the destination.
    • path: The full path to the uploaded file.

    MemoryStorage specific properties:

    • buffer: The entire file contents as a Buffer object.
  3. How Multer populates the request object

    main

    When Multer processes a request, it adds the following objects to the request (req) object:

    • req.body: Contains the values of the text fields from the form.
    • req.file: Contains the file (or files) uploaded via the form (used when a single file is uploaded).
    • req.files: Contains the uploaded files (used when multiple files are uploaded).
  4. How Multer works with Express requests

    main

    Multer is a Node.js middleware for handling multipart/form-data, primarily used for file uploads. When Multer processes a request, it populates the following properties on the request object:

    • req.body: Contains the values corresponding to the text fields of the form.
    • req.file: Contains the file object (when using .single()).
    • req.files: Contains the files (when using .array() or .fields()).

    Important: Multer will not process any form that is not multipart/form-data. Ensure your HTML form includes enctype="multipart/form-data".

  5. How Multer works with multipart/form-data

    main

    Multer is a middleware for handling multipart/form-data, primarily used for uploading files. It is built on top of busboy for efficiency.

    Important: Multer does not handle any forms other than multipart/form-data. When using Multer, you must ensure your HTML form includes the enctype="multipart/form-data" attribute.

    <form action="/profile" method="post" enctype="multipart/form-data">
      <input type="file" name="avatar" />
    </form>
  6. Implement a custom Multer storage engine

    main

    A storage engine is a class used to define how uploaded files are stored and removed. To create a custom engine, you must implement two core methods: _handleFile and _removeFile.

    Core Methods

    1. _handleFile(req, file, cb):

      • Responsible for storing the file data.
      • The file data is provided via file.stream (a readable stream).
      • You should pipe this stream to your storage destination.
      • Once the operation is complete, call the callback cb with an object containing information about the file (e.g., { path: '...' }). This object is merged with Multer's file object and becomes available in req.file or req.files.
    2. _removeFile(req, file, cb):

      • Responsible for deleting the file if an error occurs later in the request lifecycle.
      • Multer decides when to trigger this method.
      • Call the callback cb once the removal is complete.

    Implementation Guidelines

    • When defining helper functions (like a destination function), always use the signature (req, file, cb) to ensure compatibility and ease of switching between engines.
    • The destination function should return the path where the file should be saved via the callback.
    var fs = require('fs')
    
    function getDestination (req, file, cb) {
      cb(null, '/dev/null')
    }
    
    function MyCustomStorage (opts) {
      this.getDestination = (opts.destination || getDestination)
    }
    
    MyCustomStorage.prototype._handleFile = function _handleFile (req, file, cb) {
      this.getDestination(req, file, function (err, path) {
        if (err) return cb(err)
    
        var outStream = fs.createWriteStream(path)
    
        file.stream.pipe(outStream)
        outStream.on('error', cb)
        outStream.on('finish', function () {
          cb(null, {
            path: path,
            size: outStream.bytesWritten
          })
        })
      })
    }
    
    MyCustomStorage.prototype._removeFile = function _removeFile (req, file, cb) {
      fs.unlink(file.path, cb)
    }
    
    module.exports = function (opts) {
      return new MyCustomStorage(opts)
    }
  7. Create a custom storage engine

    main
    If the default storage engines (disk or memory) do not meet your requirements, you can implement your own storage engine. Detailed instructions and requirements for implementing a custom engine can be found in the StorageEngine.md documentation.
  8. Basic Usage of Multer in Express

    main

    Multer is middleware for handling multipart/form-data. It populates req.body with text fields and either req.file (for a single file) or req.files (for multiple files) with file information.

    Warning: Never use Multer as global middleware. Only apply it to specific routes that require file uploads to prevent malicious users from uploading files to unexpected routes.

    const express = require('express')
    const multer  = require('multer')
    const upload = multer({ dest: 'uploads/' })
    
    const app = express()
    
    // Handle a single file named 'avatar'
    app.post('/profile', upload.single('avatar'), function (req, res, next) {
      // req.file is the 'avatar' file
      // req.body contains text fields
    })
    
    // Handle an array of files named 'photos' (max 12)
    app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
      // req.files is the array of 'photos' files
    })
    
    // Handle mixed fields
    const uploadMiddleware = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
    app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
      // req.files is an object (String -> Array) where keys are field names
      // e.g., req.files['avatar'][0] -> File
    })
  9. Handle Multer errors in Express

    main

    When an error occurs during file upload, Multer passes the error to Express. You can handle these errors using standard Express error-handling middleware. To specifically identify errors originating from Multer, you can check if the error is an instance of multer.MulterError.

    const multer = require('multer')
    const upload = multer().single('avatar')
    
    app.post('/profile', function (req, res) {
      upload(req, res, function (err) {
        if (err instanceof multer.MulterError) {
          // An error occurred specifically within Multer during upload.
        } else {
          // An unknown error occurred during upload.
        }
    
        // If everything was successful...
      })
    })