Загрузка изображений с использованием Node.js, Express и Mongoose - PullRequest
101 голосов
/ 01 марта 2011

Пожалуйста, рассмотрите новые ответы, которые содержат более актуальную информацию, поскольку за эти годы все изменилось!

Поскольку многие новые библиотеки Node.js быстро оказываются устаревшими, иВ любом случае, это относительно немного примеров, которые я хочу задать о загрузке изображений с помощью:

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

Как другие это сделали?

Я обнаружил: node-formidable , но я новичок в загрузке изображений вОбщее, поэтому я хочу изучить общие вещи и способы сделать это с помощью Node.js и Express.

Ответы [ 12 ]

75 голосов
/ 01 марта 2011

Я отвечу на свой вопрос впервые.Я нашел пример прямо из источника.Пожалуйста, прости плохой отступ.Я не был уверен, как правильно сделать отступ при копировании и вставке.Код приходит прямо из Express multipart/form-data пример на 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');
47 голосов
/ 21 марта 2012

Поскольку вы используете экспресс, просто добавьте bodyParser:

app.use(express.bodyParser());

тогда ваш маршрут автоматически получит доступ к загруженным файлам в 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
});

Если вы называете элемент управления вводом "todo" следующим образом (в Jade):

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

Тогда загруженный файл будет готов к тому времени, когда вы получите путь и исходное имя файла в 'files.todo':

  • req.files.todo.path и
  • req.files.todo.name

другие полезные свойства req.files:

  • размер (в байтах)
  • тип (например, 'image / png')
  • lastModifiedate
  • _writeStream.encoding (например, «двоичный»)
19 голосов
/ 15 мая 2012

Вы можете сконфигурировать промежуточное программное обеспечение connect body parser в блоке конфигурации в главном файле приложения:

    /** Form Handling */
    app.use(express.bodyParser({
        uploadDir: '/tmp/uploads',
        keepExtensions: true
    }))
    app.use(express.limit('5mb'));
14 голосов
/ 13 сентября 2012

Видите ли, лучшее, что вы можете сделать, это просто загрузить изображение на диск и сохранить URL-адрес в MongoDB. Отдых, когда вы получите изображение снова. Просто укажите URL, и вы получите изображение. Код для загрузки выглядит следующим образом.

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;
            //
        });
    });
});

Теперь сохраните целевой путь в вашей базе данных MongoDB.

Опять же, при получении изображения просто извлеките URL из базы данных MongoDB и используйте его для этого метода.

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");
    }
});
9 голосов
/ 10 ноября 2011

Попробуйте этот код. Это поможет.

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);
}
8 голосов
/ 17 января 2012

Вы также можете использовать следующее, чтобы указать путь, по которому будет сохранен файл.

req.form.uploadDir = "<path>";
5 голосов
/ 30 марта 2014

I создал пример , который использует Express и Multer.Это очень просто и позволяет избежать всех подключений предупреждений

Это может кому-нибудь помочь.

2 голосов
/ 12 апреля 2014

Опять же, если вы не хотите использовать bodyParser, работает следующее:

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 голосов
/ 02 декабря 2012

В Express 3.0, если вы хотите использовать грозные события, вы должны удалить промежуточное промежуточное программное обеспечение, чтобы вы могли создать его новый экземпляр.

Для этого:

app.use(express.bodyParser());

Может быть записано как:

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

А теперь создайте объект формы:

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;
};

Я также разместил это в своем блоге, Получение грозного объекта формы в Express 3.0 при загрузке .

1 голос
/ 12 мая 2014

Я знаю, что оригинальный вопрос касался определенных версий, но он также ссылался на "последний" - пост @JohnAllen больше не актуален из-за Expressjs bodyParser и connect-form

Это демонстрирует простой в использовании встроенный 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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...