Example output
Here's a complete code snippet for handling image uploads in Node.js, using `express` for routing and `multer` for handling file uploads. The code includes validation for file type, size limit, error handling, unique file naming, and basic file management functions.
Make sure to install the necessary dependencies before running this code:
```bash
npm install express multer fs path
```
### Code Snippet
```javascript
// Required dependencies
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const app = express();
const PORT = 3000;
// Define storage configuration for multer
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './uploads'); // Set upload directory
},
filename: (req, file, cb) => {
// Use a unique filename to avoid overwriting
const uniqueName = `${Date.now()}-${Math.round(Math.random() * 1E9)}${path.extname(file.originalname)}`;
cb(null, uniqueName);
}
});
// File filter to allow only JPEG and PNG files
const fileFilter = (req, file, cb) => {
const allowedTypes = /jpeg|jpg|png/;
const extName = allowedTypes.test(path.extname(file.originalname).toLowerCase());
const mimeType = allowedTypes.test(file.mimetype);
if (extName && mimeType) {
cb(null, true);
} else {
cb(new Error('Only .jpeg, .jpg, and .png files are allowed!'));
}
};
// Set multer configuration
const upload = multer({
storage: storage,
limits: { fileSize: 2 * 1024 * 1024 }, // Set size limit to 2MB
fileFilter: fileFilter
}).single('image'); // Expect a single file with key name 'image'
// Route to handle file upload
app.post('/upload', (req, res) => {
upload(req, res, (err) => {
if (err instanceof multer.MulterError) {
// Handle multer-specific errors
return res.status(400).json({ error: err.message });
} else if (err) {
// Handle other errors
return res.status(400).json({ error: err.message });
}
if (!req.file) {
return res.status(400).json({ error: 'No file uploaded' });
}
res.status(200).json({
message: 'File uploaded successfully!',
filename: req.file.filename
});
});
});
// Route to retrieve a file by filename
app.get('/uploads/:filename', (req, res) => {
const filePath = path.join(__dirname, 'uploads', req.params.filename);
fs.access(filePath, fs.constants.F_OK, (err) => {
if (err) {
return res.status(404).json({ error: 'File not found' });
}
res.sendFile(filePath);
});
});
// Route to delete a file by filename
app.delete('/uploads/:filename', (req, res) => {
const filePath = path.join(__dirname, 'uploads', req.params.filename);
fs.unlink(filePath, (err) => {
if (err) {
return res.status(404).json({ error: 'File not found or already deleted' });
}
res.status(200).json({ message: 'File deleted successfully' });
});
});
// Route to list all uploaded files
app.get('/uploads', (req, res) => {
fs.readdir('./uploads', (err, files) => {
if (err) {
return res.status(500).json({ error: 'Could not retrieve files' });
}
res.status(200).json({ files });
});
});
// Start the server
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
```
### Explanation of the Code
1. **Storage Configuration**: `multer.diskStorage` is configured to set the destination directory to `./uploads` and provide each file a unique name using a timestamp and a random number.
2. **File Filter**: The `fileFilter` function checks if the uploaded file is in JPEG or PNG format by validating both the MIME type and file extension.
3. **Upload Middleware**: Multer is configured with `storage`, file size limits, and the `fileFilter`. This middleware is applied in the `/upload` route to handle file upload.
4. **Upload Route (`/upload`)**: Handles the upload process, providing error handling for both multer-specific and general errors. If no file is uploaded, it returns an error.
5. **Retrieve Route (`/uploads/:filename`)**: Allows users to retrieve files by filename if they exist in the `uploads` directory.
6. **Delete Route (`/uploads/:filename`)**: Allows users to delete files by filename, with error handling if the file is not found.
7. **List Route (`/uploads`)**: Lists all files in the `uploads` directory.
### Notes
- The file size limit is set to 2 MB, but this can be adjusted.
- Ensure the `uploads` directory exists in your project root, or add code to create it if it doesn't exist.
- This code assumes a single-file upload and expects the file to have the form-data key `image`.