[Node.js] 익스프레스 - 파일 업로드 기능 만들기 (multer 미들웨어)

익스프레스에서는 외장 모듈을 사용해서 파일 업로드 기능을 만들 수 있다. 파일을 업로드 할 때는 멀티 파트(multipart) 포맷으로 된 파일 업로드 기능을 사용하며 파일 업로드 상태 등을 확인할 수 있다.

multer 미들웨어 사용하기

multer 미들웨어로 파일을 업로드하는 방법을 알아보자. cmd에서 프로젝트 폴더로 들어가서 npm i multer --save로 설치한다. 코드를 작성 전에 유의할 것은 미들웨어 사용 순서(body-parser - multer - router 순)가 중요하다는 것이다.

이제 /public/photo.html에서 파일 업로드 웹 페이지를 만들고 업로드를 구현해보자.

/public/photo.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>파일 업로드 테스트</title>
</head>
<body>
   <h1>파일 업로드</h1>
   <hr>
   <form method="post" enctype="multipart/form-data" action="/process/photo">
       <input type="file" name="photo">
       <input type="submit" name="submit" value="업로드">
   </form>
</body>
</html>
cs

<form> 태그 안의 <input> 태그의 type 속성 값으로 file을 입력하면 멀티파트 포맷으로 서버에 업로드를 요청할 수 있다. <form> 태그의 method 속성은 post, enctype 속성은 multipart/form-data로 설정한다. 요청할 URL의 정보인 /process/photo는 action 속성에 넣어준다.

app.js
var express = require('express'),
    http = require('http'),
    path = require('path');
 
var bodyParser = require('body-parser'),
    static = require('serve-static'),
    cookieParser = require('cookie-parser'),
    expressSession = require('express-session');
 
var multer = require('multer'),
    fs = require('fs'),
    cors = require('cors');
 
var app = express();
var router = express.Router();
 
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
 
app.use('/public', static(path.join(__dirname, 'public')));
app.use('/uploads', static(path.join(__dirname, 'uploads')));
 
app.use(cookieParser());
app.use(expressSession({
    secret: 'my key',
    resave: true,
    saveUninitialized: true
}));
 
app.use(cors()); //ajax 요청시 CORS(다중서버접속) 지원
 
var storage = multer.diskStorage({
    destination: function (req, file, callback){
        callback(null'uploads/')
    },
    filename: function (req, file, callback){
        callback(null, file.originalname + '-' + Date.now())
    }
});
 
var upload = multer({
    storage: storage,
    limits: {
        files: 10//파일개수제한 10개
        fileSize: 1024 * 1024 * 1024 //파일크기제한 1GB
    }
});
 
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 i=0; i<files.length; i++){
                originalname = files[i].originalname;
                filename = files[i].filename;
                mimetype = files[i].mimetype;
                size = files[i].size;
            }
        }
        
        console.log("현재 파일 정보: " + originalname + ', ' + filename + ', ' + mimetype + ', ' + size);
        
        res.writeHead('200', {
            'Content-Type''text/html;charset=utf8'
        });
        res.write('<h1>업로드 성공</h1>');
        res.write('<hr />');
        res.write('<p>원본 파일이름: ' + originalname + '-> 저장 파일이름: ' + filename + '</p>');
        res.write('<p>MIMETYPE: ' + mimetype + '</p>');
        res.write('<p>SIZE: ' + size + '</p>');
        res.end();
    } catch(err) {
        console.dir(err.stack);
    }
});
 
app.use('/', router);
 
http.createServer(app).listen(3000function () {
    console.log('Express 서버가 3000번 포트에서 시작');
})
cs

코드가 길지만 POST 방식의 요청이 이루어졌을 경우(파일을 업로드할 경우) 파일의 정보를 확인하고 클라이언트에 응답을 보내는 것이 전부이다. 업로드한 파일의 정보를 확인할 때는 req.files 배열에 들어있는 원소들을 참조한다.

파일을 업로드했을 떄 업로드한 파일의 정보는 배열 객체에 저장된다. 여기서 for문으로 배열 객체의 요소들인 이름, 크기를 하나씩 확인 후 할당한다.

서버를 실행한 후 localhost:3000/public/photo.html로 접속하여 파일을 업로드하면 파일의 속성이 출력될 것이다. 브라켓 콘솔 창도 확인해보자.

댓글 없음:

Powered by Blogger.