Use multipart form data for uploads, stream large files to object storage like S3, validate file types server-side, and provide upload progress feedback.
File uploads require coordination between frontend, backend, and storage, with attention to security and user experience.
Frontend: use <input type="file"> or drag-and-drop libraries. FormData sends files as multipart/form-data. Show upload progress using XMLHttpRequest's progress events or fetch with ReadableStream. Let users preview images before upload.
Backend: use middleware (multer for Express) to parse multipart data. For small files, buffer in memory; for large files, stream directly to storage. Never trust client file extensions—validate MIME types server-side using magic bytes.
Object storage (S3, Cloudflare R2, GCS) is better than local filesystem for production. It scales independently, provides CDN integration, and handles backup/redundancy. Generate presigned URLs to let clients upload directly to storage, bypassing your server.
Direct-to-storage uploads: server generates a presigned URL with limited validity, client uploads directly to storage using that URL, then notifies server of completion. This reduces server load for large files.
Security considerations: limit file sizes, validate types strictly (not just extensions), scan for malware for sensitive applications, store files with generated names (not user-provided), and serve user uploads from a different domain to prevent XSS.
For images, consider processing services (Cloudinary, Imgix) that resize, optimize, and serve appropriate formats automatically. They handle the complexity of responsive images.
Use multipart form data for uploads, stream large files to object storage like S3, validate file types server-side, and provide upload progress feedback.
Join our network of elite AI-native engineers.