Gereksinimler ve Ön Hazırlık
Çalışmaya başlamadan önce sisteminizde Node.js'in güncel bir LTS (Long Term Support) sürümünün yüklü olduğundan emin olun. Projenizi başlatmak için bir terminal açın ve aşağıdaki adımları takip ederek gerekli paketleri yükleyin.
# Proje klasörünü oluşturun
mkdir dosya-yukleme-projesi
cd dosya-yukleme-projesi
# Node.js projesini başlatın
npm init -y
# Gerekli paketleri yükleyin
npm install express multer
Bu komutlar, projenizin temel yapısını oluşturur ve Express ile Multer kütüphanelerini node_modules klasörüne ekler. Multer, Node.js'in dosya yükleme işlemlerini yöneten en popüler middleware (ara yazılım) çözümüdür.
Multer Depolama Motoru Yapılandırması
Multer'in en güçlü özelliği DiskStorage motorudur. Bu motor, dosyaların nereye kaydedileceğini ve dosyaların nasıl isimlendirileceğini kontrol etmenizi sağlar. Dosya isimlerinin çakışmaması için benzersiz (unique) isimler oluşturmak kritik bir güvenlik ve yönetim adımıdır.
const multer = require('multer');
const path = require('path');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/'); // Dosyaların kaydedileceği klasör
},
filename: function (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 });
Yukarıdaki kod, uploads/ adında bir klasör tanımlar ve her dosyaya zaman damgası ekleyerek benzersiz bir isim verir. Bu yöntem, aynı isimli dosyaların birbirinin üzerine yazılmasını engeller.
Çoklu Dosya Yükleme İçin Route Tanımlama
Multer, çoklu dosya yükleme işlemleri için array metodunu sunar. Bu metod, formdan gelen belirli bir anahtar (key) altındaki tüm dosyaları bir dizi olarak işler. Aşağıdaki örnekte, 'fotograflar' isimli alandan gelen maksimum 5 dosyayı kabul eden bir yapı kuruyoruz.
const express = require('express');
const app = express();
app.post('/yukle', upload.array('fotograflar', 5), (req, res) => {
if (!req.files || req.files.length === 0) {
return res.status(400).send('Dosya yüklenmedi.');
}
res.send({ mesaj: 'Dosyalar başarıyla yüklendi', dosyalar: req.files });
});
upload.array('fotograflar', 5) ifadesi, istemciden gelen 'fotograflar' isimli input alanından en fazla 5 dosya beklediğimizi belirtir. Eğer kullanıcı daha fazla dosya yüklemeye çalışırsa, Multer otomatik olarak hata fırlatacaktır.
Güvenlik: Dosya Filtreleme ve Doğrulama
Sunucunuza rastgele dosya türlerinin (örneğin .exe veya .php) yüklenmesi büyük bir güvenlik açığıdır. Bu nedenle, sadece izin verdiğimiz MIME tiplerini (image/jpeg, image/png gibi) kabul etmeliyiz.
const fileFilter = (req, file, cb) => {
const izinVerilenTipler = ['image/jpeg', 'image/png', 'image/webp'];
if (izinVerilenTipler.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error('Sadece JPEG, PNG ve WEBP formatları desteklenir!'), false);
}
};
const upload = multer({ storage: storage, fileFilter: fileFilter });
Bu filtreleme mekanizması, dosya içeriğini kontrol etmeden önce MIME tipini doğrular. Bu, kötü niyetli kullanıcıların sunucunuza zararlı betikler yüklemesini engellemek için ilk savunma hattınızdır.
Kritik Güvenlik Uyarısı: Sadece MIME tipi kontrolü yeterli değildir. Üretim ortamında (production), yüklenen dosyaların içeriğini de tarayan (örneğin antivirüs taraması) ek güvenlik katmanları kullanmalı ve yüklenen dosyaları doğrudan çalıştırılabilir dizinlerde tutmamalısınız.
Multer Entegrasyon Yöntemleri Karşılaştırması
| Yöntem | Kullanım Amacı | Avantajı |
|---|---|---|
single() |
Tekil dosya yükleme | Basit ve hızlı |
array() |
Aynı isimde çoklu dosya | Toplu işlem kolaylığı |
fields() |
Farklı isimlerde çoklu dosya | Esnek form yapısı |
Hata Yönetimi ve Debug İpuçları
Multer hataları genellikle Express'in standart hata işleyicilerine düşer. Kullanıcıya net mesajlar vermek için bir "Error Handling Middleware" kullanmanız önerilir.
app.use((err, req, res, next) => {
if (err instanceof multer.MulterError) {
return res.status(400).json({ hata: 'Multer Hatası: ' + err.message });
} else if (err) {
return res.status(500).json({ hata: err.message });
}
next();
});
Bu yapı, dosya boyutu aşıldığında veya dosya tipi desteklenmediğinde uygulamanızın çökmesini engeller ve kullanıcıya anlamlı bir JSON yanıtı döner.
Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Dosya yükleme sistemlerinde oluşabilecek veri kaybı, güvenlik ihlali veya sunucu kaynaklı sorunlardan kullanıcı sorumludur. Üretim ortamında her zaman dosya boyutlarını sınırlandırın ve yükleme dizinini düzenli olarak temizleyin.
Sıkça Sorulan Sorular
Multer ile yüklenen dosyaların boyutunu nasıl sınırlarım?
Multer konfigürasyonunda limits nesnesini kullanarak fileSize değerini bayt cinsinden belirleyebilirsiniz. Örneğin: limits: { fileSize: 1024 * 1024 * 5 } ile 5MB sınır koyabilirsiniz.
Yüklenen dosyaları veritabanında nasıl tutmalıyım?
Dosyaları doğrudan veritabanına (BLOB olarak) kaydetmek performans açısından önerilmez. Dosyaları diskte veya bulut depolama servislerinde (AWS S3 vb.) tutun ve veritabanına sadece dosyanın yolunu (path) kaydedin.
Farklı dosya türlerini farklı klasörlere nasıl ayırırım?
destination fonksiyonu içerisinde file.mimetype değerini kontrol ederek, koşullu bir şekilde farklı klasör yolları döndürebilirsiniz.
Multer neden dosyalarımı kaydetmiyor?
Genellikle dosya yolu (path) hatasıdır. uploads/ klasörünün projenizin ana dizininde mevcut olduğundan emin olun. Node.js'in bu klasöre yazma yetkisi (write permission) olup olmadığını kontrol edin.
Multer ile dosya ismini dinamik olarak nasıl değiştirebilirim?
filename fonksiyonu içerisinde req.body verilerine erişebilirsiniz. Örneğin, kullanıcının ID'sini dosya isminin başına ekleyerek dosyaları kullanıcı bazlı sınıflandırabilirsiniz.
Multer ile Yüklenen Görselleri Optimize Etme ve Boyutlandırma
Dosya yükleme süreçlerinde en sık karşılaşılan sorunlardan biri, kullanıcıların çok yüksek boyutlu görseller yüklemesidir. Multer tek başına dosyayı diske kaydetmekle görevlidir; ancak Sharp kütüphanesi ile birleştirildiğinde, dosyalar diske yazılmadan önce veya yazıldıktan hemen sonra işlenebilir. Bu, sunucu depolama alanından tasarruf etmenizi ve istemci tarafında daha hızlı görsel yüklenmesini sağlar.
Aşağıdaki örnekte, Multer ile gelen dosyayı bir ara katman (middleware) kullanarak nasıl yeniden boyutlandıracağınızı görebilirsiniz:
const sharp = require('sharp');
const fs = require('fs');
const resizeImages = async (req, res, next) => {
if (!req.files) return next();
await Promise.all(
req.files.map(async (file) => {
const newFilename = `resized-${file.filename}`;
await sharp(file.path)
.resize(800, 800)
.toFormat('jpeg')
.jpeg({ quality: 90 })
.toFile(`uploads/resized/${newFilename}`);
})
);
next();
};
Üretim Ortamında (Production) Performans ve Güvenlik İpuçları
Geliştirme ortamında çalışan kodunuz, canlıya alındığında farklı darboğazlarla karşılaşabilir. Özellikle yüksek trafikli uygulamalarda dosya yükleme süreçlerini optimize etmek kritiktir.
1. Dosya Yüklemelerini Bellek (MemoryStorage) Üzerinden Yönetin
Eğer dosyalarınız çok küçükse (örneğin profil fotoğrafları), disk yerine MemoryStorage kullanarak dosyaları RAM üzerinde tutabilir ve doğrudan bulut depolama servislerine (AWS S3, Google Cloud Storage) yönlendirebilirsiniz. Bu, sunucu diskine yazma yükünü tamamen ortadan kaldırır.
2. Dosya Yükleme Limitlerini İstemci Tarafında da Kontrol Edin
Multer tarafında limits yapılandırması ile dosya boyutunu sınırlamak bir güvenlik önlemidir, ancak kullanıcı deneyimi için bu kontrolü Frontend tarafında da yapmalısınız. Kullanıcıya dosya yükleme aşamasında "Dosya boyutu çok büyük" uyarısı vermek, sunucuya gereksiz veri gönderilmesini engeller.
3. Dosya İsimlerini Rastgeleleştirin (UUID)
Güvenlik nedeniyle, kullanıcıların yüklediği orijinal dosya isimlerini asla olduğu gibi kaydetmeyin. Bu, "Directory Traversal" saldırılarına zemin hazırlayabilir. Bunun yerine uuid kütüphanesini kullanarak benzersiz isimler oluşturun:
const { v4: uuidv4 } = require('uuid');
const path = require('path');
const storage = multer.diskStorage({
destination: 'uploads/',
filename: (req, file, cb) => {
const uniqueName = `${uuidv4()}${path.extname(file.originalname)}`;
cb(null, uniqueName);
}
});
4. Yükleme Klasörlerini Temizleme (Cleanup)
Sisteminizde uzun süre kalan geçici dosyalar veya hatalı yüklemeler disk alanınızı tüketebilir. Belirli aralıklarla (örneğin node-cron kullanarak) uploads/ klasörünü tarayan ve 24 saatten eski dosyaları silen bir temizlik betiği çalıştırmanız önerilir.
const cron = require('node-cron');
const fs = require('fs');
// Her gün gece yarısı çalışır
cron.schedule('0 0 * * *', () => {
const directory = 'uploads/';
fs.readdir(directory, (err, files) => {
if (err) throw err;
for (const file of files) {
// Dosya yaşı kontrolü ve silme işlemleri burada yapılır
}
});
});
Sonuç
Node.js ve Multer kullanarak çoklu dosya yükleme sistemini entegre etmek, doğru yapılandırıldığında oldukça güvenli ve verimli bir süreçtir. Bu rehberde; depolama motorunu kurmayı, dosya filtrelemeyi, çoklu dosya işlemeyi ve hata yönetimini öğrendiniz. Bir sonraki adım olarak, yüklenen dosyaları AWS S3 gibi bulut tabanlı bir depolama servisine aktarmayı veya yüklenen görselleri sharp kütüphanesi ile otomatik olarak yeniden boyutlandırmayı deneyebilirsiniz.


Yorumlar (0)
Yorum Yaz