it-swarm.com.de

Bilder mit Node.js, Express und Mongoose hochladen

Bitte berücksichtigen Sie neuere Antworten, die aktuellere Informationen enthalten, da sich die Dinge im Laufe der Jahre geändert haben!

Da viele neue Node.js-Bibliotheken schnell veraltet sind und es relativ wenige Beispiele gibt, möchte ich nach dem Hochladen von Bildern fragen:

  • Node.js (v0.4.1)
  • Express (1.0.7)
  • Mungo (1.1.0).

Wie haben es andere gemacht?

Ich habe gefunden: node-formidable , aber ich kann Bilder generell nicht hochladen, also möchte ich allgemeines Zeug und Wege lernen, wie man Node.js und Express verwendet.

99
JohnAllen

Ich beantworte meine eigene Frage zum ersten Mal. Ich habe ein Beispiel direkt von der Quelle gefunden. Bitte verzeihen Sie die schlechte Einrückung. Ich war mir nicht sicher, wie ich beim Kopieren und Einfügen richtig einrücken sollte. Der Code stammt direkt von Express multipart/form-data example auf GitHub.

// Expose modules in ./support for demo purposes
require.paths.unshift(__dirname + '/../../support');

/**
 * Module dependencies.
 */

var express = require('../../lib/express')
  , form = require('connect-form');

var app = express.createServer(
  // connect-form (http://github.com/visionmedia/connect-form)
  // middleware uses the formidable middleware to parse urlencoded
  // and multipart form data
  form({ keepExtensions: true })
);

app.get('/', function(req, res){
  res.send('<form method="post" enctype="multipart/form-data">'
    + '<p>Image: <input type="file" name="image" /></p>'
    + '<p><input type="submit" value="Upload" /></p>'
    + '</form>');
});

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

  // connect-form adds the req.form object
  // we can (optionally) define onComplete, passing
  // the exception (if any) fields parsed, and files parsed
  req.form.complete(function(err, fields, files){
    if (err) {
      next(err);
    } else {
      console.log('\nuploaded %s to %s'
        ,  files.image.filename
        , files.image.path);
      res.redirect('back');
    }
  });

  // We can add listeners for several form
  // events such as "progress"
  req.form.on('progress', function(bytesReceived, bytesExpected){
    var percent = (bytesReceived / bytesExpected * 100) | 0;
    process.stdout.write('Uploading: %' + percent + '\r');
  });
});

app.listen(3000);
console.log('Express app started on port 3000');
75
JohnAllen

Da Sie express verwenden, fügen Sie einfach bodyParser hinzu:

app.use(express.bodyParser());

ihre Route hat dann automatisch Zugriff auf die hochgeladenen Dateien in req.files:

app.post('/todo/create', function (req, res) {
    // TODO: move and rename the file using req.files.path & .name)
    res.send(console.dir(req.files));  // DEBUG: display available fields
});

Wenn Sie das Eingabesteuerelement "todo" wie folgt benennen (in Jade):

form(action="/todo/create", method="POST", enctype="multipart/form-data")
    input(type='file', name='todo')
    button(type='submit') New

Dann ist die hochgeladene Datei fertig, sobald Sie den Pfad und den ursprünglichen Dateinamen in 'files.todo' erhalten:

  • req.files.todo.path und
  • req.files.todo.name

andere nützliche Eigenschaften der Requiredfiles:

  • größe (in Bytes)
  • typ (z. B. "image/png")
  • lastModifiedate
  • _writeStream.encoding (z. B. 'binary')
47
Brent Faust

Sie können die Connect Body Parser-Middleware in einem Konfigurationsblock in Ihrer Hauptanwendungsdatei konfigurieren:

    /** Form Handling */
    app.use(express.bodyParser({
        uploadDir: '/tmp/uploads',
        keepExtensions: true
    }))
    app.use(express.limit('5mb'));
19
srquinn

Das Beste, was Sie tun können, ist, das Image einfach auf die Festplatte hochzuladen und die URL in MongoDB zu speichern. Ruhen Sie sich aus, wenn Sie das Bild erneut abrufen. Geben Sie einfach die URL an und Sie erhalten ein Bild. Der Code zum Hochladen lautet wie folgt.

app.post('/upload', function(req, res) {
    // Get the temporary location of the file
    var tmp_path = req.files.thumbnail.path;
    // Set where the file should actually exists - in this case it is in the "images" directory.
    target_path = '/tmp/' + req.files.thumbnail.name;
    // Move the file from the temporary location to the intended location
    fs.rename(tmp_path, target_path, function(err) {
        if (err)
            throw err;
        // Delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files.
        fs.unlink(tmp_path, function() {
            if (err)
                throw err;
            //
        });
    });
});

Speichern Sie nun den Zielpfad in Ihrer MongoDB-Datenbank.

Extrahieren Sie beim Abrufen des Bildes einfach die URL aus der MongoDB-Datenbank und verwenden Sie sie für diese Methode.

fs.readFile(target_path, "binary", function(error, file) {
    if(error) {
        res.writeHead(500, {"Content-Type": "text/plain"});
        res.write(error + "\n");
        res.end();
    }
    else {
        res.writeHead(200, {"Content-Type": "image/png"});
        res.write(file, "binary");
    }
});
14
Nilesh

Versuchen Sie diesen Code. Es wird helfen.

app.get('/photos/new', function(req, res){
  res.send('<form method="post" enctype="multipart/form-data">'
    + '<p>Data: <input type="filename" name="filename" /></p>'
    + '<p>file: <input type="file" name="file" /></p>'
    + '<p><input type="submit" value="Upload" /></p>'
    + '</form>');
});


 app.post('/photos/new', function(req, res) {
  req.form.complete(function(err, fields, files) {
    if(err) {
      next(err);
    } else {
      ins = fs.createReadStream(files.photo.path);
      ous = fs.createWriteStream(__dirname + '/directory were u want to store image/' + files.photo.filename);
      util.pump(ins, ous, function(err) {
        if(err) {
          next(err);
        } else {
          res.redirect('/photos');
        }
      });
      //console.log('\nUploaded %s to %s', files.photo.filename, files.photo.path);
      //res.send('Uploaded ' + files.photo.filename + ' to ' + files.photo.path);
    }
  });
});

if (!module.parent) {
  app.listen(8000);
  console.log("Express server listening on port %d, log on to http://127.0.0.1:8000", app.address().port);
}
9
Dar Hamid

Sie können auch Folgendes verwenden, um einen Pfad festzulegen, in dem die Datei gespeichert wird.

req.form.uploadDir = "<path>";
8
Manuela

Ich habe ein Beispiel erstellt , das Express und Multer verwendet. Es ist sehr einfach und vermeidet alle Connect - Warnungen

Es könnte jemandem helfen.

5
Jon J

Wenn Sie unter Express 3.0 die formidierbaren Ereignisse verwenden möchten, müssen Sie die mehrteilige Middleware entfernen, damit Sie die neue Instanz davon erstellen können.

Um dies zu tun:

app.use(express.bodyParser());

Kann geschrieben werden als:

app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart()); // Remove this line

Erstellen Sie nun das Formularobjekt:

exports.upload = function(req, res) {
    var form = new formidable.IncomingForm;
    form.keepExtensions = true;
    form.uploadDir = 'tmp/';

    form.parse(req, function(err, fields, files){
        if (err) return res.end('You found error');
        // Do something with files.image etc
        console.log(files.image);
    });

    form.on('progress', function(bytesReceived, bytesExpected) {
        console.log(bytesReceived + ' ' + bytesExpected);
    });

    form.on('error', function(err) {
        res.writeHead(400, {'content-type': 'text/plain'}); // 400: Bad Request
        res.end('error:\n\n'+util.inspect(err));
    });
    res.end('Done');
    return;
};

Ich habe dies auch in meinem Blog gepostet: Formulierbares Formularobjekt in Express 3.0 beim Hochladen abrufen.

2
Risto Novik

Wenn Sie bodyParser nicht verwenden möchten, funktioniert Folgendes:

var express = require('express');
var http = require('http');
var app = express();

app.use(express.static('./public'));


app.configure(function(){
    app.use(express.methodOverride());
    app.use(express.multipart({
        uploadDir: './uploads',
        keepExtensions: true
    }));
});


app.use(app.router);

app.get('/upload', function(req, res){
    // Render page with upload form
    res.render('upload');
});

app.post('/upload', function(req, res){
    // Returns json of uploaded file
    res.json(req.files);
});

http.createServer(app).listen(3000, function() {
    console.log('App started');
});
2
Squidinker

Ich weiß, dass sich die ursprüngliche Frage auf bestimmte Versionen bezog, aber sie bezog sich auch auf den "neuesten" - Post von @JohnAllen, da Expressjs bodyParser und connect-form nicht mehr relevant sind.

Dies demonstriert den benutzerfreundlichen eingebauten bodyParser ():

 /**
 * Module dependencies.
 */

var express = require('express')

var app = express()
app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/home/svn/rest-api/uploaded' }))

app.get('/', function(req, res){
  res.send('<form method="post" enctype="multipart/form-data">'
    + '<p>Image: <input type="file" name="image" /></p>'
    + '<p><input type="submit" value="Upload" /></p>'
    + '</form>');
});

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

    res.send('Uploaded: ' + req.files.image.name)
    return next()

});

app.listen(3000);
console.log('Express app started on port 3000');
1
GMeister

Hier können Sie Ihre Bilder mit dem Paket "formidable" hochladen, das in späteren Versionen von Express gegenüber bodyParser empfohlen wird. Dazu gehört auch die Möglichkeit, Ihre Bilder im Handumdrehen in der Größe anzupassen:

Von meiner Website: Hochladen und Skalieren von Bildern (on the fly) mit Node.js und Express .

Hier ist der Gist:

var express = require("express"),
app = express(),
formidable = require('formidable'),
util = require('util')
fs   = require('fs-extra'),
qt   = require('quickthumb');

// Use quickthumb
app.use(qt.static(__dirname + '/'));

app.post('/upload', function (req, res){
  var form = new formidable.IncomingForm();
  form.parse(req, function(err, fields, files) {
    res.writeHead(200, {'content-type': 'text/plain'});
    res.write('received upload:\n\n');
    res.end(util.inspect({fields: fields, files: files}));
  });

  form.on('end', function(fields, files) {
    /* Temporary location of our uploaded file */
    var temp_path = this.openedFiles[0].path;
    /* The file name of the uploaded file */
    var file_name = this.openedFiles[0].name;
    /* Location where we want to copy the uploaded file */
    var new_location = 'uploads/';

    fs.copy(temp_path, new_location + file_name, function(err) {  
      if (err) {
        console.error(err);
      } else {
        console.log("success!")
      }
    });
  });
});

// Show the upload form 
app.get('/', function (req, res){
  res.writeHead(200, {'Content-Type': 'text/html' });
  /* Display the file upload form. */
  form = '<form action="/upload" enctype="multipart/form-data" method="post">'+ '<input name="title" type="text" />
  '+ '<input multiple="multiple" name="upload" type="file" />
  '+ '<input type="submit" value="Upload" />'+ '</form>';
  res.end(form); 
}); 
app.listen(8080);

HINWEIS: Dies erfordert Image Magick für die schnelle Größenänderung des Daumens.

0
Tony Spiro

Es gibt meine Methode, mehrere Dateien hochzuladen:

Nodejs:

router.post('/upload', function(req , res) {

var multiparty = require('multiparty');
var form = new multiparty.Form();
var fs = require('fs');

form.parse(req, function(err, fields, files) {  
    var imgArray = files.imatges;


    for (var i = 0; i < imgArray.length; i++) {
        var newPath = './public/uploads/'+fields.imgName+'/';
        var singleImg = imgArray[i];
        newPath+= singleImg.originalFilename;
        readAndWriteFile(singleImg, newPath);           
    }
    res.send("File uploaded to: " + newPath);

});

function readAndWriteFile(singleImg, newPath) {

        fs.readFile(singleImg.path , function(err,data) {
            fs.writeFile(newPath,data, function(err) {
                if (err) console.log('ERRRRRR!! :'+err);
                console.log('Fitxer: '+singleImg.originalFilename +' - '+ newPath);
            })
        })
}
})

Stellen Sie sicher, dass Ihr Formular enctype = "multipart/form-data" hat.

Ich hoffe das gibt dir eine Hand;)

0
Despertaweb