Wissen

KNOW-HOW FÜR FORTSCHRITT

Dieser Artikel befasst sich mit einem flexiblen und schnell umsetzbaren Datei-Upload in NodeJS. Dabei wird der Einsatz von Busboy sowohl an einem Beispiel mit und einem ohne die Verwendung von ExpressJS aufgezeigt.
Ein sehr beliebter Anwendungsfall für dieses Thema wäre ein Bilder-Upload für eine eigene API.

Voraussetzung

Erfahrungen in folgenden Bereichen:

  • Aufbau einer NodeJS App
  • Funktionsweise von Middlewares für ExpressJS

Busboy

Das kleine aber feine NodeJS Modul ist nichts anderes als ein Parser für HTML-Formular-Daten. Darunter fallen natürlich auch als Spezialfall Daten vom Typ File.

Über folgenden Befehl kann Busboy installiert werden:

npm install busboy

Einfacher NodeJS Server

Simple NodeJS Server sind normale http-Server, die sich an einen Port hängen und alle Anfragen an diesen von der NodeJS-App entgegengenommen werden.

var http = require('http');

http.createServer().listen(8000, function() {
    console.log('NodeJS Server hört auf Port 8000');
});

Als nächstes muss Busboy in unsere App eingebunden werden.

var http = require('http'),
    Busboy = require('busboy');

http.createServer().listen(8000, function() {
    console.log('NodeJS Server hört auf Port 8000');
});

Jetzt kann auf Anfragen gehört und geprüft werden, ob dort Formular-Daten vom Typ File enthalten sind.

var http = require('http'),
    Busboy = require('busboy');

http.createServer(function (request, response) {
    // Falls POST-Request
    if (request.method === 'POST') {
        // erzeuge neue Busboy-Instanz und setze Request-Headers
        var busboy = new Busboy({ headers: request.headers });
        // benutze Busboy, um ankommende Daten zu parsen
        request.pipe(busboy);
        // Multipart-Formdata vom Typen File
        busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
            // Event wenn Daten übermittelt werden (data.length sind die übertragenen Bytes)
            file.on('data', function(data) {
                ...
            });
            // Event wenn die Datei fertig übertragen wurde
            file.on('end', function() {
                ...
            });
        });
        // Busboy hat alle Formulardaten fertig verarbeitet
        busboy.on('finish', function() {
            res.writeHead(200, {Connection: 'close' });
            res.end();
        });
    }
}).listen(8000, function() {
    console.log('NodeJS Server hört auf Port 8000');
});

Im letzten Schritt muss die hochgeladene Datei nur noch auf der Festplatte gespeichert werden. Dafür wird das schon in NodeJS enthaltene filsystem Module fs benutzt.

var http = require('http'),
    fs = require('fs'),
    Busboy = require('busboy');

http.createServer(function (request, response) {
    // Falls POST-Request
    if (request.method === 'POST') {
        // erzeuge neue Busboy-Instanz und setze Request-Headers
        var busboy = new Busboy({ headers: request.headers });
        // benutze Busboy, um ankommende Daten zu parsen
        request.pipe(busboy);

        // Multipart-Formdata vom Typen File
        busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
            // Leitet alle Daten der Datei in eine Datei weiter
            file.pipe(fs.createWriteStream('PFAD/' + filename));
        });

        // Busboy hat alle Formulardaten fertig verarbeitet
        busboy.on('finish', function() {
        // Sende Antwort zum Client
            res.writeHead(200, {Connection: 'close' });
            res.end();
        });
    }
}).listen(8000, function() {
    console.log('NodeJS Server hört auf Port 8000');
});

Im Grunde war das auch schon der einfachste Fall eines Datei-Uploads ;).

Express NodeJS Server

Dafür wird zu Beginn erst einmal das entsprechende Express-Module benötigt:

npm install express

Eine einfache Express App würde dann wie folgt aussehen:

var express = require('express'),
    app = express();

app.listen(8000, function () {
    console.log('NodeJS Server hört auf Port 8000');
});

Der nächste Schritt ist die Einbindung von Busboy.
Durch die Erweiterung connect-busboy kann der Schritt zur Erzeugung der neuen Busboy Instanz weggelassen werden.

npm install connect-busboy
var express = require('express'),
    busboy = require('connect-busboy'),
    fs = require('fs'),
    app = express();

// Packt busboy Instanz auf request.busboy
app.use(busboy());

app.listen(8000, function () {
    console.log('NodeJS Server hört auf Port 8000');
});

// Definition für POST-Requests an die URL '/api/upload'
app.post('/api/upload', function (req, res) {
    // Benutze Busboy Parser
    req.pipe(req.busboy);

    // Für jede empfangene Datei
    req.busboy.on('file', function (fieldname, file, filename) {
        // Schreibe die Datei auf die Festplatte
        file.pipe(fs.createWriteStream('PFAD/' + filename));
    });

    // Busboy hat alle Formulardaten fertig verarbeitet
    req.busboy.on('finish', function() {
        // Sende Antwort zum Client
        res.send();
    });
});

Fazit

Mit Busboy lassen sich flexibel und schnell generische Upload-Lösungen implementieren. Die Busboy-Middleware erlaubt außerdem das automatische Parsen normaler Formular-Felder.
ExpressJS bietet jedoch schon sehr gute eigene Request-Body-Parser, weshalb es empfehlenswert ist nur bei wirklichen Upload-Anfragen Busboy zu benutzen.
Stellt die NodeJS-App eine Schnittstelle zur Verfügung, können mit Hilfe von ExpressJS schnell und einfach URL-Schemen umgesetzt werden. Dadurch können spezielle Requests (wie Datei-Uploads) von den restlichen separiert werden.

Wir freuen uns über eine Bewertung, um ein Feedback zu erhalten:

Durchschnittlich 4.7 Sterne aus 3 Meinungen.