Node.js İle Çoklu Dosya Yükleme İçin Multer Entegrasyonu Nasıl Yapılır?

Node.js İle Çoklu Dosya Yükleme İçin Multer Entegrasyonu Nasıl Yapılır?
Node.js İle Çoklu Dosya Yükleme İçin Multer Entegrasyonu Nasıl Yapılır?

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.

Bu yazıya tepkinizi paylaşın:
Pelin Aydın

Kullanıcı deneyimi odaklı içerik stratejileri geliştiriyorum. Pratik bilgi arayan okuyucular için en hızlı ve etkili yöntemleri içeren rehberler hazırlıyorum.

Yorumlar (17)

17
okuyucu bu yazı hakkında yorum yaptı. Siz de deneyiminizi paylaşarak diğer okuyuculara yardımcı olabilirsiniz.
Caner Yılmaz
Caner Yılmaz 31 Temmuz 2026

Eline sağlık Pelin, Multer ile uğraşırken hep dosya ismi çakışmalarında hata alıyordum, diskStorage kısmı çok açıklayıcı olmuş.

Pelin Aydın
Pelin Aydın 01 Ağustos 2026

Beğenmene sevindim Caner! Dosya isimlerini Date.now() ile birleştirmek o çakışma sorununu kökten çözüyor, denedin mi?

Selin G.
Selin G. 01 Ağustos 2026

Ya ben kodları aynen kopyaladım ama 400 bad request hatası alıyorum sürekli. `enctype` kısmını da unutmadım aslında, nerede hata yapıyor olabilirim?

Burak Çelik
Burak Çelik 02 Ağustos 2026

Selin, `app.use` kısmındaki middleware sırasına dikkat et, bazen body-parser ile çakışabiliyor.

Mertcan Öztürk
Mertcan Öztürk 02 Ağustos 2026

Güzel yazı olmuş, teşekkürler. Peki bu dosyaları buluta (S3 gibi) yüklemek istersek mantık çok değişir mi?

Pelin Aydın
Pelin Aydın 03 Ağustos 2026

Teşekkürler Mertcan. S3 için `multer-s3` kütüphanesini kullanman gerekiyor, temel mantık yine aynı ama storage yapılandırması değişiyor.

Deniz K.
Deniz K. 03 Ağustos 2026

Süper anlatım valla, kaç gündür arıyodum böyle sade bi rehber. Çok işime yaradı, eline sağlık.

Pelin Aydın
Pelin Aydın 04 Ağustos 2026

İşine yaramasına çok sevindim Deniz, kolay gelsin!

Zeynep Arslan
Zeynep Arslan 04 Ağustos 2026

Dosya boyutu kısıtlamasını nerden yapıyoruz? Onu göremedim yazıda, büyük dosya yüklenince patlamasın server.

Hakan Vural
Hakan Vural 05 Ağustos 2026

Zeynep, limits objesiyle yapılabiliyor. `limits: { fileSize: 1024 * 1024 * 5 }` gibi eklemen lazım.

Berk E.
Berk E. 05 Ağustos 2026

Abi çok güzel anlatmışsın da keşke resimleri yüklerken otomatik boyutlandıran bi örnekte ekleseydin, tam süper olurdu.

Ayşe Yılmaz
Ayşe Yılmaz 05 Ağustos 2026

Yazı güzel ama kod blokları biraz daha belirgin olabilirmiş mobilde kayıyor gibi sanki. Yinede emeğe sağlık.

Pelin Aydın
Pelin Aydın 06 Ağustos 2026

Geri bildirimin için teşekkürler Ayşe, tema üzerinde düzenleme yapacağım.

Fatih Demir
Fatih Demir 06 Ağustos 2026

Dosya türü filtreleme (fileFilter) kısmını anlamadım pek, sadece jpeg kabul etmek için nasıl bi yol izliyoruz?

Pelin Aydın
Pelin Aydın 06 Ağustos 2026

Fatih, fileFilter içinde `file.mimetype` kontrolü yaparak istediğin formatları filtreleyebilirsin, bir sonraki yazıda buna detaylı değineceğim.

Emre Can
Emre Can 06 Ağustos 2026

Node.js tarafında multer dışında başka alternatifler de var mı? Yoksa standart bu mu?

Seda Nur
Seda Nur 06 Ağustos 2026

Çok açıklayıcı olmuşş, teşekkürler. Hemen deniyorum projemde.

Yorum Yaz