Programing

Node.js, Express 및 Mongoose를 사용하여 이미지 업로드

crosscheck 2020. 8. 18. 07:12
반응형

Node.js, Express 및 Mongoose를 사용하여 이미지 업로드


수년에 걸쳐 상황이 변함에 따라 더 최신 정보가있는 최신 답변을 고려하십시오!

많은 새로운 Node.js 라이브러리가 빠르게 구식으로 렌더링되고 있기 때문에 어쨌든 다음을 사용하여 이미지 업로드에 대해 물어보고 싶은 예가 상대적으로 적습니다.

  • Node.js (v0.4.1)
  • Express (1.0.7)
  • 몽구스 (1.1.0).

다른 사람들은 어떻게 했습니까?

나는 발견했다 : node-formidable , 그러나 나는 일반적으로 이미지를 업로드하는 것이 처음이므로 Node.js 및 Express를 사용하여 일반적인 내용과 그렇게하는 방법을 배우고 싶습니다.


제 질문에 처음으로 답하겠습니다. 소스에서 직접 예를 찾았습니다. 들여 쓰기 불량은 용서해주십시오. 복사하여 붙여 넣을 때 제대로 들여 쓰기하는 방법을 잘 모르겠습니다. 코드는 GitHub의 Express multipart/form-data예제 에서 직접 가져온 것 입니다.

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

express를 사용하고 있으므로 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 (예 : 'binary')

기본 애플리케이션 파일의 구성 블록에서 연결 본문 파서 미들웨어를 구성 할 수 있습니다.

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

가장 좋은 방법은 이미지를 디스크에 업로드하고 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 데이터베이스에 대상 경로를 저장하십시오.

다시 말하지만 이미지를 검색하는 동안 MongoDB 데이터베이스에서 URL을 추출하여이 방법에 사용하면됩니다.

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

이 코드를 시도하면 도움이 될 것입니다.

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

다음을 사용하여 파일을 저장할 경로를 설정할 수도 있습니다.

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

나는 예를 들어 생성 된 Express 및 Multer를 사용합니다. 매우 간단하며 모든 Connect 경고를 피합니다.

누군가를 도울 수 있습니다.


다시 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');
});

For Express 3.0, if you want to use the formidable events, you must remove the multipart middleware, so you can create the new instance of it.

To do this:

app.use(express.bodyParser());

Can be written as:

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

And now create the form object:

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

I have also posted this on my blog, Getting formidable form object in Express 3.0 on upload.


I know that the original question related to specific versions, but it also referred to the "latest" - @JohnAllen 's post is no longer relevant due to Expressjs bodyParser and connect-form

This demonstrates the easy to use in-built 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');

There's my method to multiple upload file:

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

Make sure your form has enctype="multipart/form-data"

I hope this gives you a hand ;)


Here's a way to upload your images using the formidable package, which is recommended over bodyParser in later versions of Express. This also includes the ability to resize your images on the fly:

From my website: Uploading and Resizing Images (on the fly) With Node.js and Express.

Here's the 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);

NOTE: This requires Image Magick for the quick thumb resizing.

참고URL : https://stackoverflow.com/questions/5149545/uploading-images-using-node-js-express-and-mongoose

반응형