본문 바로가기

블록체인_9기/💚 Node.js

40강_230530_Node.js(multer)

728x90

 

목차

040

 

 

 


multer

  • 이미지, 동영상 등의 여러 가지 파일들을 멀티파트 형식으로 업로드할 때 시용하는 미들웨어이다.
    • 멀티파트 형식?
      • enctype이 multipart/form-data인 폼을 통해 업로드하는 데이터의 형식을 의미한다.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <form action="/upload" method="post" enctype="multipart/form-data"> <!-- 멀티파트 폼 데이터 -->
        <input type="file" name="image">
        <input type="text" name="title">
        <button type="submit">Submit</button>
    </form>
</body>
</html>

 

multer 문법

  • storage : 저장할 공간에 대한 정보이다. 디스크나 메모리 저장이 가능하다.
  • diskStorage : 하드디스크에 업로드 파일을 저장한다.
  • destination : 저장할 경로이다.
  • filename : 저장할 파일명이다. (파일명 + 날짜 + 확장자 형식)
  • Limits : 파일 개수나 파일 사이즈를 제한할 수 있다.
const multer = require('multer');
const fs = require('fs');

//------ multer를 설정하여 사용하기 위해서 서버에 upload 폴더가 꼭 존재해야 하므로 fs모듈로 서버를 시작할 때 생성한다.
try {
	fs.readdirSync('uploads'); // 폴더 확인
} catch(err) {
	console.error('uploads 폴더가 없습니다. 폴더를 생성합니다.');
    fs.mkdirSync('uploads'); // 폴더 생성
}

const upload = multer({
    storage: multer.diskStorage({ // 저장한공간 정보 : 하드디스크에 저장
        destination(req, file, done) { // 저장 위치
            done(null, 'uploads/'); // uploads라는 폴더 안에 저장
        },
        filename(req, file, done) { // 파일명을 어떤 이름으로 올릴지
            const ext = path.extname(file.originalname); // 파일의 확장자
            done(null, path.basename(file.originalname, ext) + Date.now() + ext); // 파일이름 + 날짜 + 확장자 이름으로 저장
        }
    }),
    limits: { fileSize: 5 * 1024 * 1024 } // 5메가로 용량 제한
});
// => 이렇게 설정한 upload라는 객체를 뒤에 라우터에 장착하면 된다.

 

위에서 선언한 upload 객체의 변수에는 다양한 종류의 미들웨어가 존재한다. 미들웨어는 single,. array, field, none이 있다.

upload.single()

  • 파일을 하나만 업로드 하는 경우에 사용하는 미들웨어이다.
// 단순 웹페이지 get요청 들어오면 html을 띄워준다.
app.get('/upload', (req, res) => {
	res.sendFile(path.join(__dirname, 'multipart.html'));
}

// 위에서 설정한 upload 객체 변수를 라우터에 장착 한다.
// 이미지 업로드 같은 동작은 특정 라우터에만 일어나기 때문에, app.use()에는 장착하지 않는 편이다.
app.post('/upload', upload.single('image'), (req, res) => { // 'image'라는 이름은 multipart.html의 <input type="file" name="image"> 에서 폼데이터 이름으로 온 것이다.
    
    // upload.single('image')의 업로드 정보가 req.file에 넣어진다.
    // <input type="text" name="title"> 의 텍스트 정보가 req.body에 넣어진다.
    console.log(req.file, req.body); 
    res.send('ok');
})


//req.file은 다음과 같이 불러와진다.------------------------------------------------
{
    fieldname: 'img',
    originalname: 'hello.png',
    encoding: '7bit',
    mimetype: 'image/png',
    destination: 'uploads/',
    filename: 'hello1567238581123.png',
    path: 'uploads//hello1567238581123.png',
    size: 44933
}

 

upload.array()

  • 여러 파일을 업로드하는 경우엔 HTML의 input 태그에 multiple을 사용한다.

HTML

<form name="이 폼의 이름" action="이 데이터들을 받을 파일" method="post" enctype="multipart/form-data">
     <input type='file' name='many' multiple/>
</form>

JavaScript

  • 미들웨어를 single 대신 array로 교체하여 사용한다.
  • 업로드된 정보들은 배열로 저장된다.
app.post('/upload', upload.array('many'), (req, res) => {
    console.log(req.files); // 업로드 결과도 req.file 대신 req.files 배열에 들어간다
    res.send('ok');
});

 

upload.field()

  • 한 번에 파일을 여러 개 업로드하는 것이 아닌, 따로따로 업로드를 여러 개 하는 경우에 사용한다.
  • input 태그나 form 데이터의 키가 다른 경우에 사용한다.

HTML

<form action="/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="image1">
  <input type="file" name="image2">
  <input type="file" name="image3">
  <input type="text" name="title">
  <button type="submit">Submit</button>
</form>

JavaScript

  • fileds 미들웨어를 사용하고, 인수로 input 태그들의 name들을 각각 적는다.
  • limits으로 이미지의 업로드 개수를 설정할 수 있다.
    • limits : 5 => 이미지를 5장까지만 넣을 수 있다는 말이다.
app.post('/upload',
    upload.fields([{ name: 'image1', limits: 5 }, { name: 'image2' }, { name: 'image3' }]), // 배열 객체를 넣는다.
    (req, res) => {
    	// 업로드 결과는 각각 req.files.image1, req.files.image2에 들어간다.
        console.log(req.files.image1);
        console.log(req.files.image2);
        console.log(req.files.image3);
        res.send('ok');
    }
);

 

upload.none()

  • 파일이 아님에도 멀티파트 형식으로 업로드 해야하는 특수한 경우에 사용한다.
    • 예) new FormData()
app.post('/upload', upload.none(), (req, res) => {
    console.log(req.body.title); // 이 경우 파일을 업로드하지 않으므로 req.body만 존재한다.
    res.send('ok');
});

 

 

 

 

 

 

 

 

 

 

728x90