Dit lijkt een vrij eenvoudige vraag te zijn, maar ik vind het heel moeilijk om erachter te komen hoe ik dit moet aanpakken.
Ik gebruik Node.js + Express om een webtoepassing te bouwen, en ik vind de connect BodyParser die express blootstelt in de meeste gevallen erg handig. Ik zou echter graag meer gedetailleerde toegang hebben tot meerdelige formuliergegevens-POSTS zodra ze komen – ik moet de invoerstroom naar een andere server sturen en wil voorkomen dat ik eerst het hele bestand download.
Omdat ik de Express BodyParser gebruik, worden alle bestandsuploads echter automatisch geparseerd en geüpload en beschikbaar gemaakt met “request.files” voordat ze ooit bij een van mijn functies komen.
Is er een manier waarop ik de BodyParser kan uitschakelen voor meerdelige formdata-berichten zonder deze voor al het andere uit te schakelen?
Antwoord 1, autoriteit 100%
Als je de functionaliteit van express.bodyParser
wilt gebruiken, maar deze wilt uitschakelen voor multipart/form-data, is de truc om express.bodyParser directly
. express.bodyParser
is een gemaksmethode die drie andere methoden omvat: express.json
, express.urlencoded
en express.multipart
.
Dus in plaats van te zeggen
app.use(express.bodyParser())
je hoeft alleen maar te zeggen
app.use(express.json())
.use(express.urlencoded())
Dit geeft u alle voordelen van de bodyparser voor de meeste gegevens, terwijl u de uploads van formuliergegevens onafhankelijk kunt afhandelen.
Bewerken:json
en urlencoded
worden nu niet meer gebundeld met Express. Ze worden geleverd door de afzonderlijke module body-parseren u gebruikt ze nu als volgt:
bodyParser = require("body-parser")
app.use(bodyParser.json())
.use(bodyParser.urlencoded())
Antwoord 2, autoriteit 44%
Als de noodzaak voor body-parsing alleen afhangt van de route zelf, is het eenvoudigste om bodyParser
te gebruiken als een route-middleware-functie op alleen de routes die het nodig hebben, in plaats van het app-breed te gebruiken:
var express=require('express');
var app=express.createServer();
app.post('/body', express.bodyParser(), function(req, res) {
res.send(typeof(req.body), {'Content-Type': 'text/plain'});
});
app.post('/nobody', function(req, res) {
res.send(typeof(req.body), {'Content-Type': 'text/plain'});
});
app.listen(2484);
Antwoord 3, autoriteit 29%
Als u app.use(express.bodyParser())
typt, gaat bijna elk verzoek door de bodyParser
-functies (welke wordt uitgevoerd, hangt af van content-type
kop).
Standaard worden er 3 headers ondersteund (AFAIR). Voor de zekerheid zou je bronnen kunnen raadplegen. U kunt handlers voor content-type
‘s (her)definiëren met zoiets als dit:
var express = require('express');
var bodyParser = express.bodyParser;
// redefine handler for Content-Type: multipart/form-data
bodyParser.parse('multipart/form-data') = function(req, options, next) {
// parse request body your way; example of such action:
// https://github.com/senchalabs/connect/blob/master/lib/middleware/multipart.js
// for your needs it will probably be this:
next();
}
upd.
Er zijn dingen veranderd in Express 3, dus ik deel bijgewerkte code van een werkend project (moet app.use
ed voorexpress.bodyParser()
):
var connectUtils = require('express/node_modules/connect/lib/utils');
/**
* Parses body and puts it to `request.rawBody`.
* @param {Array|String} contentTypes Value(s) of Content-Type header for which
parser will be applied.
* @return {Function} Express Middleware
*/
module.exports = function(contentTypes) {
contentTypes = Array.isArray(contentTypes) ? contentTypes
: [contentTypes];
return function (req, res, next) {
if (req._body)
return next();
req.body = req.body || {};
if (!connectUtils.hasBody(req))
return next();
if (-1 === contentTypes.indexOf(req.header('content-type')))
return next();
req.setEncoding('utf8'); // Reconsider this line!
req._body = true; // Mark as parsed for other body parsers.
req.rawBody = '';
req.on('data', function (chunk) {
req.rawBody += chunk;
});
req.on('end', next);
};
};
En wat pseudo-code, met betrekking tot de oorspronkelijke vraag:
function disableParserForContentType(req, res, next) {
if (req.contentType in options.contentTypes) {
req._body = true;
next();
}
}
Antwoord 4, autoriteit 24%
Binnen Express 3 kun je de parameter doorgeven aan de bodyParser
als {defer: true}
– wat in term de verwerking van meerdere delen uitstelt en het Formidable-formulierobject blootstelt als req. formulier. Dit betekent dat uw code kan zijn:
...
app.use(express.bodyParser({defer: true}));
...
// your upload handling request
app.post('/upload', function(req, res)) {
var incomingForm = req.form // it is Formidable form object
incomingForm.on('error', function(err){
console.log(error); //handle the error
})
incomingForm.on('fileBegin', function(name, file){
// do your things here when upload starts
})
incomingForm.on('end', function(){
// do stuff after file upload
});
// Main entry for parsing the files
// needed to start Formidables activity
incomingForm.parse(req, function(err, fields, files){
})
}
Voor meer gedetailleerde afhandeling van formidabele gebeurtenissen raadpleegt u https://github.com/felixge/node-formidable
Antwoord 5, autoriteit 6%
Ik heb soortgelijke problemen ondervonden in 3.1.1 en heb een (niet zo mooie IMO) oplossing gevonden:
om bodyParser voor multipart/form-data uit te schakelen:
var bodyParser = express.bodyParser();
app.use(function(req,res,next){
if(req.get('content-type').indexOf('multipart/form-data') === 0)return next();
bodyParser(req,res,next);
});
en voor het ontleden van de inhoud:
app.all('/:token?/:collection',function(req,res,next){
if(req.get('content-type').indexOf('multipart/form-data') !== 0)return next();
if(req.method != 'POST' && req.method != 'PUT')return next();
//...use your custom code here
});
Ik gebruik bijvoorbeeld node-multiparty waar de aangepaste code er als volgt uit zou moeten zien:
var form = new multiparty.Form();
form.on('file',function(name,file){
//...per file event handling
});
form.parse(req, function(err, fields, files) {
//...next();
});
Antwoord 6, autoriteit 5%
Met express v4 en body-parser v1.17 en hoger,
U kunt een functie doorgeven in het type
van bodyParser.json.
body-parser zal alleen die invoer ontleden waar deze functie een waarheidswaarde retourneert.
app.use(bodyParser.json({
type: function(req) {
return req.get('content-type').indexOf('multipart/form-data') !== 0;
},
}));
In de bovenstaande code,
de functie retourneert een valse waarde als het content-type
multipart/form-data
is.
Het analyseert de gegevens dus niet wanneer het content-type
multipart/form-data
is.
Antwoord 7, autoriteit 2%
gooi dit voor app.configure
delete express.bodyParser.parse['multipart/form-data'];