2014-05-12 15 views
7

Potrzebuję prostego sposobu na uzyskanie dostępu do danych formularza wieloczęściowego w obiekcie referencyjnym za pomocą połączenia typu busboy-connect. Używam Express 4, który teraz potrzebuje modułów dla wcześniej wbudowanej funkcjonalności.Jak uzyskać dostęp do obiektu Express 4 req.body przy użyciu Busboy

Chcę, aby obiekt req.body był dostępny na moich trasach, ale funkcja busboy.on ("pole") jest asynchroniczna i nie przetwarza wszystkich danych formularza przed jego pominięciem, aby kontynuować kod.

Istnieje moduł oprogramowania pośredniego zbudowany na górze busboy o nazwie multer, który pobiera obiekt req.body przed dotarciem do trasy, jednak nadpisuje możliwość zdefiniowania zdarzenia busboy.on ("plik") z poziomu trasa.

Oto mój złamany kod:

// 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 Używam połączyć-boy hotelowy. Użyłem tego kodu pośredniego w moim pliku konfiguracji ekspresowej, aby uzyskać dostęp do obiektu req.body na mojej trasie. Mogę również przetworzyć przesyłanie plików z mojej trasy i mieć dostęp do req.busbuy.on ("koniec").

// 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

Mam ten sam problem Czy myśli wyjaśniając, jak ten kod działa? Wszystkie moje żądania są obsługiwane osobnymi trasami, a to rozwiązanie nie działa dla mojego kodu. Być może, gdybym lepiej zrozumiał, co robisz, pomoże mi to rozwiązać mój problem! To mój pierwszy projekt węzłowy. – Jeffpowrs

+0

@JeffPowers Nie mogłem uruchomić oprogramowania pośredniego tak, jak myślałem. Nie ma aktualnego rozwiązania do analizowania przychodzących danych wieloczęściowych w "różnych" lokalizacjach, takich jak tylko analiza pól, a następnie zrobienie czegoś z danymi pól, następnie przeanalizowanie pliku później, a następnie wywołanie busboy.on ("zakończ"). Proszę zobaczyć mój post tutaj: http: //programmers.stackexchange.com/questions/239170/how-to-parse-multipart-field-file-data-separately daj mi znać, jeśli coś znajdziesz. Skończyło się na tym, że wprowadziłem tonę logiki do mojego kontrolera. Nie był to dobry wybór, ale zrezygnowałem. – Scott

+0

Doszedłem do tego samego wniosku, że faktycznie zamieniłem busboy na multer: https://github.com/expressjs/multer. To było o wiele prostsze. – Jeffpowrs

Odpowiedz

9

spróbuj dodać:

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

To była wskazówka, której potrzebowałem. Dokonałem edycji OP, aby odzwierciedlić moje rozwiązanie. Jest to oprogramowanie pośrednie, ale nie sądzę, że spowalnia przychodzące posty. – Scott

+1

Możesz skrócić swoje rozwiązanie do poziomu 'req.busboy.on ('finish', next);' – mscdex

+0

Wpadłem na inny problem. Próbuję zachować poprawne oddzielenie problemów w aplikacji mojego węzła. Do tej pory mój przepływ jest taki: 1. app.js: skonfiguruj oprogramowanie pośredniczące, aby uzyskać dane z wieloczęściowych danych. Muszę użyć natychmiast = true. 2. routes.js: zdefiniuj trasę/post, przekaż ją kontrolerowi. 3. controller.js: użyj obiektu req.body, aby sformatować dane, utwórz nowy obiekt modelu, wywołaj model.save (req.body) (który rozpoczyna proces przesyłania zdjęć). 4. model.js: wykorzystuje dane busboy + req.body do przesłania obrazu na serwer. Czy istnieje sposób, aby najpierw przetworzyć pytanie, a następnie przejść do zdarzenia przesyłania plików? – Scott