ExpressJs

⌘K
  1. Home
  2. Docs
  3. ExpressJs
  4. multer অ্যাডভান্স middlew...
  5. Middleware হেল্পার মেথড

Middleware হেল্পার মেথড

1. Update the uploadHelper.js to include a size check within the middleware configuration:

const path = require('path');
const fs = require('fs');

// 1. Helper method: File size limit
const limitFileSize = (maxSize) => {
  return {
    fileSize: maxSize
  };
};

// 2. Helper method: File type filter
const fileFilter = (allowedTypes) => (req, file, cb) => {
  const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
  const mimetype = allowedTypes.test(file.mimetype);

  if (extname && mimetype) {
    return cb(null, true);
  } else {
    return cb(new Error('File type is not allowed.'));
  }
};

// 3. Helper method: Ensure directory exists
const ensureDirExists = (dir) => {
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true });
  }
};

// 4. Helper method: Generate unique file name
const generateFileName = (req, file, cb) => {
  const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
  const ext = path.extname(file.originalname);
  cb(null, file.fieldname + '-' + uniqueSuffix + ext);
};

// 5. Helper method: Destination directory
const destination = (req, file, cb) => {
  cb(null, path.join(__dirname, '../uploads/'));
};

// Export the helper methods
module.exports = {
  limitFileSize,
  fileFilter,
  ensureDirExists,
  generateFileName,
  destination,
};

Update the multer Configuration to Use limitFileSize:

uploadMiddleware.js:

const multer = require('multer');
const { destination, generateFileName, limitFileSize, fileFilter } = require('./uploadHelper');

// Create a storage configuration using helper methods
const storage = multer.diskStorage({
  destination: destination, // Use the helper method to set the destination directory
  filename: generateFileName, // Use the helper method to generate the file name
});

// Use the `limitFileSize` helper to set the file size limit (e.g., 5 MB)
const upload = multer({
  storage: storage, // Use the custom storage configuration
  limits: limitFileSize(5 * 1024 * 1024), // Set the file size limit using the helper method
  fileFilter: fileFilter(/jpeg|jpg|png|gif/), // Allow specific file types
});

module.exports = upload;

Use the Middleware in Routes:

index.js:

const express = require('express');
const upload = require('./uploadMiddleware'); // Import the multer configuration

const app = express();
const port = 3000;

// Route: Single file upload
app.post('/upload-single', upload.single('singleFile'), (req, res) => {
  res.status(200).json({
    message: 'File uploaded successfully!',
    file: req.file, // Information about the uploaded file
  });
});

// Route: Multiple file upload
app.post('/upload-multiple', upload.array('multipleFiles', 5), (req, res) => {
  res.status(200).json({
    message: 'Files uploaded successfully!',
    files: req.files, // Information about the uploaded files
  });
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

Some add Feature

Step 1: Create Helper Methods

uploadHelper.js:

const path = require('path');
const fs = require('fs');

// 1. Helper Method: File Size Limit
const limitFileSize = (maxSize) => {
  return {
    fileSize: maxSize,
  };
};

// 2. Helper Method: File Type Filter
const fileFilter = (allowedTypes) => (req, file, cb) => {
  const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
  const mimetype = allowedTypes.test(file.mimetype);

  if (extname && mimetype) {
    return cb(null, true);
  } else {
    return cb(new Error('Only specified file types are allowed!'));
  }
};

// 3. Helper Method: Ensure Directory Exists
const ensureDirExists = (dir) => {
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true });
  }
};

// 4. Helper Method: Generate Unique File Name
const generateFileName = (req, file, cb) => {
  const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
  const ext = path.extname(file.originalname);
  cb(null, file.fieldname + '-' + uniqueSuffix + ext);
};

// 5. Helper Method: Set Destination Directory
const destination = (dir) => (req, file, cb) => {
  ensureDirExists(dir); // Ensure the directory exists before saving files
  cb(null, dir);
};

// 6. Helper Method: Sanitize File Name
const sanitizeFileName = (fileName) => {
  return fileName.replace(/[^a-z0-9\.-]/gi, '_').toLowerCase();
};

// 7. Helper Method: Delete File (for cleanup)
const deleteFile = (filePath) => {
  if (fs.existsSync(filePath)) {
    fs.unlinkSync(filePath);
  }
};

// 8. Helper Method: Validate File Count
const limitNumberOfFiles = (maxFiles) => (req, res, next) => {
  if (req.files && req.files.length > maxFiles) {
    return res.status(400).json({ error: `You can upload a maximum of ${maxFiles} files.` });
  }
  next();
};

// Export the helper methods
module.exports = {
  limitFileSize,
  fileFilter,
  ensureDirExists,
  generateFileName,
  destination,
  sanitizeFileName,
  deleteFile,
  limitNumberOfFiles,
};

Step 2: Configure Multer with Advanced Options

uploadMiddleware.js:

const multer = require('multer');
const path = require('path');
const {
  destination,
  generateFileName,
  limitFileSize,
  fileFilter,
  sanitizeFileName,
} = require('./uploadHelper');

// Directory where files will be uploaded
const uploadDirectory = path.join(__dirname, '../uploads');

// Configure storage
const storage = multer.diskStorage({
  destination: destination(uploadDirectory), // Use the helper method to set the destination
  filename: (req, file, cb) => {
    const sanitizedFileName = sanitizeFileName(file.originalname);
    const ext = path.extname(sanitizedFileName);
    const baseName = path.basename(sanitizedFileName, ext);
    cb(null, `${baseName}-${Date.now()}${ext}`);
  },
});

// Configure Multer with advanced options
const upload = multer({
  storage: storage,
  limits: limitFileSize(5 * 1024 * 1024), // Limit file size to 5MB
  fileFilter: fileFilter(/jpeg|jpg|png|gif|pdf|docx/), // Allow specific file types
});

module.exports = upload;

Implement the Upload Routes

index.js:

const express = require('express');
const upload = require('./uploadMiddleware');
const { limitNumberOfFiles } = require('./uploadHelper');

const app = express();
const port = 3000;

// Route: Single file upload
app.post('/upload-single', upload.single('singleFile'), (req, res) => {
  res.status(200).json({
    message: 'File uploaded successfully!',
    file: req.file,
  });
});

// Route: Multiple file upload with a limit of 5 files
app.post('/upload-multiple', upload.array('multipleFiles', 10), limitNumberOfFiles(5), (req, res) => {
  res.status(200).json({
    message: 'Files uploaded successfully!',
    files: req.files,
  });
});

// Route: Upload with memory storage
app.post('/upload-single-memory', multer({ storage: multer.memoryStorage() }).single('singleFile'), (req, res) => {
  const fileBuffer = req.file.buffer;
  res.status(200).json({
    message: 'File uploaded successfully and stored in memory!',
    file: req.file,
  });
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

Explanation:

  1. limitFileSize: Limits the size of each uploaded file to 5MB.
  2. fileFilter: Ensures only files with specific MIME types (e.g., images and documents) are allowed.
  3. ensureDirExists: Automatically creates the upload directory if it doesn’t exist.
  4. generateFileName: Generates a unique filename to prevent overwriting.
  5. sanitizeFileName: Removes any potentially dangerous or special characters from the file name.
  6. deleteFile: Provides a utility to delete files when necessary (e.g., when replacing a file).
  7. limitNumberOfFiles: Limits the number of files that can be uploaded in a single request.

Step 4: Test the Implementation

You can now start the server and test the file upload functionality by sending POST requests to the following endpoints:

  • /upload-single: Upload a single file.
  • /upload-multiple: Upload multiple files (with a limit of 5 files).
  • /upload-single-memory: Upload a single file and store it in memory.

This setup provides a robust, secure, and flexible local upload system using Multer and helper methods to handle common file upload tasks.

How can we help?