2014-05-12 16 views
7

Ho bisogno di un modo semplice per accedere a dati di moduli multipart nell'oggetto req utilizzando busboy-connect. Sto usando Express 4, che ora ha bisogno di moduli per funzionalità incorporate in precedenza.Come accedere all'oggetto req.body Express 4 utilizzando Busboy

Desidero che l'oggetto req.body sia disponibile nei miei percorsi, ma la funzione busboy.on ('field') è asincrona e non elabora tutti i dati del modulo prima di inviarlo per continuare il codice.

C'è un modulo middleware costruito sopra il busboy chiamato multer, che ottiene l'oggetto req.body prima di arrivare al percorso, tuttavia sostituisce la possibilità di definire l'evento busboy.on ('file') dall'interno del itinerario.

Ecco il mio codice rotto:

// 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 sto usando connect-aiuto cameriere. Ho usato questo codice middleware nel mio file di installazione rapida per darmi accesso all'oggetto req.body all'interno del mio percorso. Posso anche elaborare il caricamento del file dall'interno del mio percorso e avere accesso a 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

Sto avendo lo stesso problema ti dispiace che spiega come funziona questo codice? Ho tutte le mie richieste gestite in percorsi separati e questa soluzione non funziona per il mio codice. Forse se avessi una migliore comprensione di ciò che stai facendo questo mi aiuterà a risolvere il mio problema! Questo è il mio primo progetto di nodo. – Jeffpowrs

+0

@JeffPowers Non sono riuscito a far funzionare il middleware come pensavo di avere. Non esiste una soluzione corrente per analizzare i dati Multipart in entrata in "differenti" posizioni, come solo analizzare i campi, quindi fare qualcosa con i dati dei campi, quindi analizzare il file in un secondo momento, quindi chiamare busboy.on ("finish"). Per favore vedi il mio post qui: http: //programmers.stackexchange.com/questions/239170/how-to-parse-multipart-field-file-data-separately fammi sapere se trovi qualcosa. Ho finito per mettere un sacco di logica nel mio controller ... non una buona scelta di design, ma ho rinunciato. – Scott

+0

Sono giunto alla stessa conclusione in realtà sono passato fuori dal ruolo di uomo d'affari per multer: https://github.com/expressjs/multer. Era molto più semplice. – Jeffpowrs

risposta

9

Prova ad aggiungere:

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

Questo era l'indizio di cui avevo bisogno. Ho modificato l'OP per riflettere la mia soluzione. È un middleware ma non penso che rallenti i post in arrivo. – Scott

+1

È possibile abbreviare la soluzione solo su 'req.busboy.on ('finish', next);' – mscdex

+0

Ho riscontrato un altro problema. Sto cercando di mantenere la corretta separazione delle preoccupazioni all'interno della mia app di nodo. Finora il mio flusso è così: 1. app.js: setup middleware espresso per ottenere req.body da dati multipart. Devo usare immediate = true. 2. routes.js: definisce il percorso/post, passalo al controller. 3. controller.js: utilizzare l'oggetto req.body per formattare i dati, creare un nuovo oggetto modello, chiamare model.save (req.body) (che inizia il processo di caricamento delle immagini). 4. model.js: utilizza i dati busboy + req.body per caricare un'immagine sul server. Esiste un modo per elaborare prima il req.body, quindi passare all'evento di caricamento del file? – Scott