본문 바로가기

공부/Node.js

[Node.js] express로 웹 서버 만들기(multer미들웨어, 이미지 업로드)

오늘은 저번에 이어서 multer 미들웨어를 사용하여 이미지를 업로드 해볼 것 이다.(물론 아직 서버도 뭣도 없기 때문에 업로드 장소는 local이다.)

 

npm install multer --save

 

당연하게도 multer 모듈을 먼저 다운 받아준다. 책에 쓰여있는대로 해석하자면 멀티 파트 포맷으로 된 파일 업로드 기능을 사용한다는데 아마 multer이 그것을 지원해주는 듯 하다.

 

모듈

 

이번에 코드에 들어간 모든 모듈이다.

 

var express = require('express')
    ,http = require('http')
    ,path = require('path');

//bodyParser 모듈
var bodyParser = require('body-parser')
    ,serve_static = require('serve-static')
    ,cookieParser = require('cookie-parser')
    ,errorHandler = require('errorhandler');

var expressErrorHandler = require('express-error-handler');

var expressSession = require('express-session');

var multer = require('multer');
var fs = require('fs');

var cors = require('cors');//ajax로 요청했을 대 cors 지원

 

슬슬 기능이 여러가지 생기면서 모듈이 늘어나면서 이 쯤 정리를 하고 추가된 건 추가를 하고 했다. 기존에 없었던 모듈은 errorhandler, cors, multer이 없었고 나머지는 원래 존재 하던 것들이다.

 

여기서 cors는 다중접속을 지원하도록 해주는 모듈이다.

 

var app = express();

app.set('port', process.env.PORT || 3000);

//주소를 파싱함  application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false}));

app.use(bodyParser.json());

//static으로 폴더를 미리 지정
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/uploads'));

app.use(cookieParser()); //cookieparser setting

app.use(expressSession({ //expresssession setting
    secret:'my key',
    resave:true,
    saveUninitialized:true
}));

app.use(cors());

 

그 다음 코드는 미들웨어를 사용하는 부분인데 사실상 가장 중요한 부분 중 하나이다. 이전에 이 부분을 진행했을 때는 오류가 너무 많이 나서 멘탈이 좀 안 좋았었기 때문이다. 알고보니 대부분의 오류의 원인은 미들웨어의 순서를 잘못 두어서 생긴 것이었다.

 

여기서 추가 된것은 app.use(cors());로 다중 접속 지원하겠다고 선언한거라고 보면 될 것 같다. 그리고 static으로 업로드한 이미지가 들어가게 될 폴더인 uploads도 지정해주었다.

 

미들웨어

 

var storage = multer.diskStorage({
    destination: function(req, file, callback){
        callback(null, 'uploads')
    },
    filename : function(req, file, callback){
        callback(null, '(' + Date.now() + ')' + file.originalname);
    }
});

var upload = multer({
    storage:storage,
    limits:{
        files: 10,
        fileSize: 1024*1024*1024
    }
});

 

multer.diszkStorage라 하여 어느정도 저장될 목적지와 파일이름을 저장한다. 목적지는 uploads로 고정이며 파일 이름은 (날짜) + 파일 이름으로 저장이 된다.

 

그리고 밑에 upload는 multer로 정해놓은 한계이다 한 번에 총 10가지의 파일과 크기는 1MB이내에서 업로드가 가능하도록 구현하였다. 그리고 위에서 설정한 storage도 맞춰주었다.(저장 공간과 저장 이름)

 

라우팅

 

router.route('/process/photo').post(upload.array('photo', 1), function(req,res){
    console.log('/process/photo 호출됨');
    
    try {
        var files = req.files;
        
        console.dir('#===== 업로드된 첫번째 파일 정보 =====#');
        console.dir(req.files[0]);
        console.dir('#=====#');
        
        var originalname = '',
            filename = '',
            mimetype = '',
            size = 0;
            
            if(Array.isArray(files)){
                console.log("배열에 들어있는 파일 갯수 : %d", files.length);
                
                for(var index = 0; index < files.length; index++){
                    originalname = files[index].originalname;
                    filename = files[index].filename;
                    mimetype = files[index].mimetype;
                    size = files[index].size;
                }
            } else {
                console.log("파일 갯수 : 1");
                
                originalname = files[index].originalname;
                filename = files[index].filename;
                mimetype = files[index].mimetype;
                size = files[index].size;
            }
        
        console.log('현재 파일의 정보 : ' + originalname + ', ' + filename + ', ' + mimetype + ', ' + size);

        res.writeHead('200', {'Content-Type' : 'text/html; charset=utf8'});
        res.write('<h3>파일 업로드 성공</h3>');
        res.write('<hr/>');
        res.write('<p>원본 파일 이름 : ' + originalname + ' -> 저장 파일명 : ' + filename + '</p>');
        res.write('<p>MIME TYPE : ' + mimetype + '</p>');
        res.write('<p>파일 크기 : ' + size + '</p>');
    } catch(err) {
        console.dir(err.stack);
    }
});

 

가장 중요한 /process/photo의 구현 코드 되겠다.

 

위에서 부터 하나씩 보자면 일단 라우팅은 /process/photo로 되어있고 post방식으로 보낼 때 upload로 어느정도 포맷을 정해놓은 듯 하다. 업로드된 파일의 정보를 var로 일단 미리 변수를 만들어 놓고 파일이 들어오면 그 파일을 변수에 집어넣고 파일의 정보를 보여주고 업로드 하게 된다.

 

실행

 

실행을 위해서 localhost:3000/photo.html로 이동

 

여기서 파일을 선택해준다.

 

 

sample.png라는 파일이 현재 들어간 상태이고 업로드를 누르게 되면

 

이렇게 파일의 타입, 이름, 크기가 나오게 된다. 그럼 이제 잘 업로드 되었나 확인을 하기 위해서 탐색기에서 파일을 찾아보았다.

 

 

이렇게 날짜와 sample이라는 글자에 일치하게 들어간 것을 볼 수 있다. (이미지는 임의로 구글에서 다운 받았다.)

 

 

로그를 확인하면 더욱 자세한 내용에 대해서 알 수 있다. 위치라던가 혹은 인코딩 비트라던가...

 

일단 여기까지 파일업로드를 했다. 이제 이 파일들을 local이 아니라 DB에 저장하기 위해서 DB를 깔고 여러모로 도전해봐야할 것 같다.