2014-05-12 7 views
7

Ich brauche eine einfache Möglichkeit zum Zugriff auf mehrteilige Formulardaten im req Objekt mit Hilfe von Busboy-Connect. Ich benutze Express 4, der jetzt Module für zuvor eingebaute Funktionen benötigt.Zugriff auf Express 4 req.body-Objekt mit Busboy

Ich möchte, dass das req.body-Objekt in meinen Routen verfügbar ist, aber die Funktion busboy.on ('Feld') asynchron ist und nicht alle Formulardaten verarbeitet, bevor es übergeben wird, um den Code weiterzuführen.

Es gibt ein Middleware-Modul, das auf dem Busboy namens multer gebaut wurde. Es ruft das Objekt req.body ab, bevor es zur Route kommt. Es überschreibt jedoch die Möglichkeit, das Ereignis busboy.on ('Datei') zu definieren Route.

Hier ist mein gebrochenen Code:

// App.js 

app.post(/users, function(req, res, next){ 

    var busboy = new Busboy({ headers: req.headers }); 

    // handle text field data (code taken from multer.js) 
    busboy.on('field', function(fieldname, val, valTruncated, keyTruncated) { 
    if (req.body.hasOwnProperty(fieldname)) { 
     if (Array.isArray(req.body[fieldname])) { 
     req.body[fieldname].push(val); 
     } else { 
     req.body[fieldname] = [req.body[fieldname], val]; 
     } 
    } else { 
     req.body[fieldname] = val; 
     console.log(req.body); 
    } 
    }); 

    busboy.on('file', function(fieldname, file, filename, encoding, mimetype) { 

    tmpUploadPath = path.join(__dirname, "uploads/", filename); 
    targetPath = path.join(__dirname, "userpics/", filename); 

    self.imageName = filename; 
    self.imageUrl = filename; 

    file.pipe(fs.createWriteStream(tmpUploadPath)); 
    }); 

    req.pipe(busboy); // start piping the data. 

    console.log(req.body) // outputs nothing, evaluated before busboy.on('field') 
         // has completed. 
}); 

UPDATE Ich verwende connect-busboy. Ich habe diesen Middleware-Code in meiner Express-Setup-Datei verwendet, um mir Zugriff auf das Objekt req.body innerhalb meiner Route zu geben. Ich kann den Datei-Upload auch von meiner Route aus bearbeiten und habe Zugriff auf req.busbuy.on ('end').

// busboy middleware to grab req. post data for multipart submissions. 
app.use(busboy({ immediate: true })); 
app.use(function(req, res, next) { 
    req.busboy.on('field', function(fieldname, val) { 
    // console.log(fieldname, val); 
    req.body[fieldname] = val; 
    }); 

    req.busboy.on('finish', function(){ 
    next(); 
    }); 
}); 
+0

ich das gleiche Problem habe Sie erklären dagegen, wie dieser Code funktioniert? Ich habe alle meine Anfragen in separaten Routen behandelt und diese Lösung funktioniert nicht für meinen Code. Vielleicht, wenn ich ein besseres Verständnis davon hätte, was Sie tun würden, würde mir das helfen, mein Problem zu lösen! Dies ist mein erstes Knotenprojekt. – Jeffpowrs

+0

@JeffPowers Ich konnte die Middleware nicht so funktionieren lassen, wie ich gedacht hatte. Es gibt keine aktuelle Lösung, um eingehende Multipart-Daten an "verschiedenen" Speicherorten zu analysieren, z. B. nur die Felder analysieren, dann etwas mit den Felddaten tun, die Datei später analysieren und dann busboy.on ("finish") aufrufen. Bitte sehen Sie meinen Beitrag hier: http: //programmers.stackexchange.com/questions/239170/how-to-parse-multipart-field-file-data-separately lassen Sie mich wissen, wenn Sie etwas finden. Ich endete damit, eine Menge Logik in meinen Controller zu legen ... keine gute Design-Wahl, aber ich gab auf. – Scott

+0

Ich kam zu der gleichen Schlussfolgerung, die ich tatsächlich busboy für Multer auswechselte: https://github.com/expressjs/multer. Es war viel einfacher. – Jeffpowrs

Antwort

9

Versuchen Zugabe:

busboy.on('finish', function() { 
    // use req.body 
}); 
+0

Das war der Schlüssel, den ich brauchte. Ich habe das OP bearbeitet, um meine Lösung widerzuspiegeln. Es ist Middleware, aber ich glaube nicht, dass es eingehende Posts verlangsamt. – Scott

+1

Sie könnten Ihre Lösung auf "req.busboy.on ('finish', next) verkürzen;' – mscdex

+0

Ich habe ein anderes Problem. Ich versuche, die Problemtrennung innerhalb meiner Knoten-App beizubehalten. Bis jetzt ist mein Fluss wie folgt: 1. app.js: Setup Express-Middleware, um req.body aus mehrteiligen Daten zu erhalten. Ich muss sofort = wahr verwenden. 2. routes.js: Definieren Sie die Route/post, übergeben Sie sie an den Controller. 3. controller.js: Verwenden Sie das Objekt req.body, um Daten zu formatieren, erstellen Sie ein neues Modellobjekt, rufen Sie model.save (req.body) auf (wodurch der Bilduploadprozess gestartet wird). 4. model.js: verwendet busboy + req.body-Daten, um das Bild auf den Server hochzuladen. Gibt es eine Möglichkeit, den req.body zuerst zu verarbeiten und dann an das Dateiupload-Ereignis zu übergeben? – Scott

Verwandte Themen