Chapter 8: File Upload and Storage
Chapter 8 of 15
Chapter 8: File Upload and Storage
8.1 File Handling
File uploads require proper handling on both frontend and backend for security and performance.
// Backend - Multer for file uploads
const multer = require('multer');
const path = require('path');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
}
});
const upload = multer({
storage: storage,
limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
fileFilter: (req, file, cb) => {
const allowedTypes = /jpeg|jpg|png|gif/;
const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = allowedTypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
}
cb(new Error('Invalid file type'));
}
});
app.post('/api/upload', upload.single('image'), (req, res) => {
res.json({ file: req.file.filename });
});
8.2 Frontend File Upload
// React file upload component
function FileUpload({ onUpload }) {
const [file, setFile] = useState(null);
const [uploading, setUploading] = useState(false);
const handleFileChange = (e) => {
setFile(e.target.files[0]);
};
const handleUpload = async () => {
if (!file) return;
const formData = new FormData();
formData.append('image', file);
setUploading(true);
try {
const response = await api.post('/api/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
});
onUpload(response.data);
} catch (error) {
console.error('Upload error:', error);
} finally {
setUploading(false);
}
};
return (
<div>
<input type="file" onChange={handleFileChange} />
<button onClick={handleUpload} disabled={uploading}>
{uploading ? 'Uploading...' : 'Upload'}
</button>
</div>
);
}
8.3 Cloud Storage
// AWS S3 upload
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
async function uploadToS3(file) {
const params = {
Bucket: process.env.S3_BUCKET,
Key: `uploads/${Date.now()}-${file.originalname}`,
Body: file.buffer,
ContentType: file.mimetype
};
return await s3.upload(params).promise();
}