javascript - node - upload image multer
Cómo deshabilitar Express BodyParser para cargas de archivos(Node.js) (7)
Parece que debería ser una pregunta bastante simple, pero me está costando trabajo averiguar cómo abordarla.
Estoy usando Node.js + Express para crear una aplicación web, y me parece que la conexión BodyParser exprés expone a ser muy útil en la mayoría de los casos. Sin embargo, me gustaría tener acceso más granular a los POSTS de datos de formulario en varias partes, ya que vienen, necesito conectar el flujo de entrada a otro servidor y quiero evitar descargar todo el archivo primero.
Sin embargo, debido a que estoy usando Express BodyParser, todas las cargas de archivos se analizan automáticamente y se cargan y están disponibles usando "request.files" antes de que lleguen a alguna de mis funciones.
¿Hay alguna manera de desactivar el BodyParser para publicaciones de formularios múltiples sin desactivarlo para todo lo demás?
Con Express v4 y body-parser v1.17 y superior,
Puede pasar una función en el type
de bodyParser.json.
body-parser analizará solo las entradas donde esta función devuelve un valor de verdad.
app.use(bodyParser.json({
type: function(req) {
return req.get(''content-type'').indexOf(''multipart/form-data'') !== 0;
},
}));
En el código anterior,
la función devuelve un valor falsy si el content-type
es multipart/form-data
.
Por lo tanto, no analiza los datos cuando el content-type
es multipart/form-data
.
Cuando escribe app.use(express.bodyParser())
, casi cada solicitud pasará por bodyParser
funciones bodyParser
(cuál se ejecutará depende del encabezado Content-Type
).
Por defecto, hay 3 encabezados compatibles (AFAIR). Podrías ver las fuentes para estar seguro. Puede (re) definir controladores para Content-Type
s con algo como esto:
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.
Las cosas han cambiado en Express 3, así que estoy compartiendo el código actualizado del proyecto en funcionamiento (debe ser una aplicación app.use
antes de express.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);
};
};
Y algún pseudo-código, con respecto a la pregunta original:
function disableParserForContentType(req, res, next) {
if (req.contentType in options.contentTypes) {
req._body = true;
next();
}
}
Dentro de Express 3, puede pasar el parámetro a bodyParser
como {defer: true}
, que en términos aplaza el procesamiento multiparte y expone el objeto de formulario Formidable como req.form. Lo que significa que su código puede ser:
...
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){
})
}
Para un manejo de eventos formidable más detallado, consulte https://github.com/felixge/node-formidable
He enfrentado problemas similares en 3.1.1 y encontré la solución (no tan bonita IMO):
para deshabilitar bodyParser para multipart / form-data:
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);
});
y para analizar el contenido:
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
});
por ejemplo, estoy usando node-multiparty donde el código personalizado debería verse así:
var form = new multiparty.Form();
form.on(''file'',function(name,file){
//...per file event handling
});
form.parse(req, function(err, fields, files) {
//...next();
});
Si la necesidad de analizar el cuerpo depende solo de la ruta en sí, lo más simple es utilizar bodyParser
como una función de middleware de ruta solo en las rutas que lo necesitan en lugar de usarlo en toda la aplicación:
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);
Si necesita usar la funcionalidad provista por express.bodyParser
pero quiere deshabilitarla para multipart / form-data, el truco es no usar express.bodyParser directly
. express.bodyParser
es un método práctico que engloba otros tres métodos: express.json
, express.urlencoded
y express.multipart
.
Entonces, en vez de decir
app.use(express.bodyParser())
solo necesitas decir
app.use(express.json())
.use(express.urlencoded())
Esto le brinda todos los beneficios del analizador de cuerpo para la mayoría de los datos, al mismo tiempo que le permite manejar cargas de datos formales de forma independiente.
Editar: json
y urlencoded
ya no están incluidos con Express. Son proporcionados por el módulo de body-parser separado y ahora los usa de la siguiente manera:
bodyParser = require("body-parser")
app.use(bodyParser.json())
.use(bodyParser.urlencoded())
arroja esto antes de la app.configure
delete express.bodyParser.parse[''multipart/form-data''];