🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

So handhaben Sie Datei-Uploads in einer Node.js-API: Vollständiger Leitfaden für 2026

⏱️5 min read  ·  1,084 words

Der korrekte Umgang mit Datei-Uploads umfasst mehr als nur das Akzeptieren einer Datei – Sie benötigen Validierung, Speicherstrategie, Sicherheit und oft auch Bildverarbeitung. Dieser Leitfaden behandelt robuste Datei-Uploads in Node.js, vom einfachen lokalen Speicher bis hin zu skalierbaren Cloud-Uploads.

Übersicht über Upload-Strategien

Strategie Am besten für
Lokaler Festplattenspeicher Kleine Apps, einzelner Server
Auf Ihren Server hochladen, dann in die Cloud Verarbeitung vor der Lagerung erforderlich
Direct-to-Cloud (vorsignierte URLs) Große Dateien, Umfang, Best Practice

Einfacher Upload mit Multer

npm install multer
const multer = require('multer');
const path = require('path');

const storage = multer.diskStorage({
  destination: './uploads',
  filename: (req, file, cb) => {
    // Generate a safe, unique filename - never trust the client's name
    const unique = Date.now() + '-' + Math.round(Math.random() * 1e9);
    cb(null, unique + path.extname(file.originalname));
  },
});

const upload = multer({
  storage,
  limits: { fileSize: 5 * 1024 * 1024 },   // 5MB limit
  fileFilter: (req, file, cb) => {
    // Only allow specific types
    const allowed = ['image/jpeg', 'image/png', 'image/webp'];
    if (allowed.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new Error('Only JPEG, PNG, and WebP images allowed'));
    }
  },
});

app.post('/upload', upload.single('file'), (req, res) => {
  res.json({ filename: req.file.filename, size: req.file.size });
});

Dateien ordnungsgemäß validieren (MIME-Typ nicht allein vertrauen)

npm install file-type
const { fileTypeFromBuffer } = require('file-type');
const fs = require('fs').promises;

// The client-provided MIME type can be faked - verify actual content
async function validateFile(filePath) {
  const buffer = await fs.readFile(filePath);
  const type = await fileTypeFromBuffer(buffer);

  const allowed = ['image/jpeg', 'image/png', 'image/webp'];
  if (!type || !allowed.includes(type.mime)) {
    await fs.unlink(filePath);   // delete the invalid file
    throw new Error('Invalid file content');
  }
  return type;
}

Mehrere Dateien und Felder

// Multiple files under one field
app.post('/gallery', upload.array('photos', 10), (req, res) => {
  const files = req.files.map(f => ({ filename: f.filename, size: f.size }));
  res.json({ uploaded: files });
});

// Different fields
const uploadFields = upload.fields([
  { name: 'avatar', maxCount: 1 },
  { name: 'documents', maxCount: 5 },
]);
app.post('/profile', uploadFields, (req, res) => {
  const avatar = req.files.avatar?.[0];
  const docs = req.files.documents || [];
  res.json({ avatar: avatar?.filename, docCount: docs.length });
});

Bildbearbeitung mit Sharp

npm install sharp
const sharp = require('sharp');

// Resize and optimize uploaded images
async function processImage(inputPath, outputPath) {
  await sharp(inputPath)
    .resize(1200, 1200, { fit: 'inside', withoutEnlargement: true })
    .webp({ quality: 80 })       // convert to WebP, compress
    .toFile(outputPath);
}

// Generate a thumbnail
async function makeThumbnail(inputPath, thumbPath) {
  await sharp(inputPath)
    .resize(200, 200, { fit: 'cover' })
    .toFile(thumbPath);
}

Direkter Upload in die Cloud mit vorsignierten URLs (optimal für Skalierung)

Leiten Sie bei großen Dateien und Größenordnungen Uploads nicht über Ihren Server – lassen Sie Clients direkt auf S3 hochladen, indem Sie eine vorsignierte URL verwenden, die Ihr Backend generiert:

const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');

const s3 = new S3Client({ region: 'us-east-1' });

// Backend: generate a presigned upload URL
app.post('/upload-url', async (req, res) => {
  const { filename, contentType } = req.body;
  const key = `uploads/${Date.now()}-${filename}`;

  const command = new PutObjectCommand({
    Bucket: 'my-bucket',
    Key: key,
    ContentType: contentType,
  });
  const uploadUrl = await getSignedUrl(s3, command, { expiresIn: 300 });

  res.json({ uploadUrl, key });
});
// Frontend: upload directly to S3, bypassing your server
const { uploadUrl, key } = await fetch('/upload-url', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ filename: file.name, contentType: file.type }),
}).then(r => r.json());

await fetch(uploadUrl, {
  method: 'PUT',
  headers: { 'Content-Type': file.type },
  body: file,   // uploads straight to S3 - no server bottleneck
});

Sicherheitscheckliste

  • Dateityp nach Inhalt validieren, nicht nur der MIME-Typ des Clients (der gefälscht werden kann)
  • Dateigröße begrenzen auf jeder Ebene (Multer, Nginx, Cloud)
  • Sichere Dateinamen generieren — Niemals den Dateinamen des Clients direkt verwenden (Pfaddurchquerungsrisiko)
  • Außerhalb des Webstamms speichern oder im Cloud-Speicher, nicht in einem öffentlich zugänglichen Verzeichnis, das Uploads ausführen könnte
  • Auf Malware prüfen wenn Dateien von nicht vertrauenswürdigen Benutzern akzeptiert werden
  • Legen Sie den richtigen Inhaltstyp und die richtige Inhaltsdisposition fest beim Zurückgeben von Dateien

Häufig gestellte Fragen

F: Sollen Uploads über meinen Server oder direkt in den Cloud-Speicher erfolgen?
A: Für kleine Dateien oder wenn Sie diese zuerst verarbeiten müssen, über Ihren Server (Multer). Verwenden Sie für große Dateien und Größenordnungen vorsignierte URLs, damit Clients sie direkt auf S3 hochladen. Dadurch werden die Bandbreiten- und Größenbeschränkungen Ihres Servers umgangen und die Skalierung ist weitaus besser.

F: Warum sollte ich dem MIME-Typ des Clients nicht vertrauen?
A: Der Content-Type-Header wird vom Client gesteuert und kann leicht gefälscht werden – ein Angreifer könnte eine schädliche Datei hochladen, die als Bild gekennzeichnet ist. Überprüfen Sie den tatsächlichen Dateiinhalt mit einem bibliotheksähnlichen Dateityp, der die magischen Bytes der Datei liest.

F: Wie gehe ich mit sehr großen Datei-Uploads um?
A: Verwenden Sie vorsignierte URLs für den direkten Upload in die Cloud (kein Serverengpass) oder implementieren Sie geblockte/fortsetzbare Uploads für große Dateien. Erhöhen Sie die Größenbeschränkungen auf allen Ebenen (Multer, Nginx, Cloud), wenn Sie über Ihren Server weiterleiten. Für große Dateien ist jedoch die direkte Übertragung in die Cloud besser.

F: Wo soll ich hochgeladene Dateien speichern?
A: Cloud-Objektspeicher (S3, GCS, R2) für Skalierbarkeit und Zuverlässigkeit – nicht auf der Festplatte Ihres App-Servers (die nicht über Instanzen hinweg skaliert und verloren geht, wenn der Server ersetzt wird). Bei kleinen Einzelserver-Apps funktioniert die lokale Festplatte, Sie planen jedoch eine Migration zum Cloud-Speicher, wenn Sie wachsen.

F: Wie verhindere ich, dass hochgeladene Dateien ausgeführt werden?
A: Speichern Sie Uploads außerhalb des Web-Roots oder im Cloud-Speicher, generieren Sie zufällige Dateinamen, validieren Sie den Inhaltstyp und stellen Sie Dateien mit den richtigen Headern bereit (Content-Disposition: Anhang für Downloads). Speichern Sie Benutzer-Uploads niemals in einem Verzeichnis, in dem der Webserver sie als Skripte ausführen würde.

Fazit

Die Handhabung von Datei-Uploads in Node.js erfordert mehr als das Akzeptieren einer Datei. Verwenden SieMulter für serverseitige Uploads mit Größenbeschränkungen und Typfilterung, Validierung von Dateien anhand des tatsächlichen Inhalts (nicht des MIME-Typs des Clients) und Verarbeitung von Bildern mit Sharp. Für große und große Dateien verwenden SieVorsignierte URLs, damit Kunden direkt in den Cloud-Speicher hochladen können, unter Umgehung Ihres Servers. Befolgen Sie immer Sicherheitspraktiken: Validieren Sie Inhalte, begrenzen Sie die Größe, generieren Sie sichere Dateinamen und speichern Sie Dateien im Cloud-Speicher oder außerhalb des Web-Roots. Um Uploads richtig zu gestalten, müssen Komfort, Leistung und Sicherheit in Einklang gebracht werden – Direct-to-Cloud mit ordnungsgemäßer Validierung ist die moderne Best Practice für die meisten Anwendungen.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা