multer

younghyun·2022년 10월 12일
0

multer 모듈

이미지, 동영상 등을 비롯한 여러 가지 파일들을 멀티파트 형식으로 업로드할 때 사용하는 미들웨어 입니다.
멀티파트 형식이란 enctype이 multipart/form-data 인 폼을 통해 업로드하는 데이터의 형식을 의미합니다.

multer 모듈 사용 방법

multer 문법

multer 패키지 안에는 여러 종류의 미들웨어가 들어있습니다.

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

multer에 넣은 인수 들은 다음과 같습니다.

먼저 storage 속성에 어디에 (destination) 어떤 이름으로 (filename) 저장할지를 넣었습니다.
두 함수 req 매개변수에는 요청에 대한 정보file 객체에는 업로드한 파일에 대한 정보가 있으며, done 매개변수는 함수입니다.

done() 함수는 첫 번째 인수에는 에러가 있다면 에러를 넣고, 두 번째 인수에는 실제 경로나 파일 이름을 넣어주면 됩니다.
req나 file의 데이터를 가공해 done으로 넘기는 식이다.

현재 설정으로는 uploads라는 폴더에 [파일명 + 현재시간.확장자] 파일명으로 업로드하는 것을 볼 수 있습니다.
limits 속성에는 업로드에 대한 제한 사항을 걸어두었습니다.
위 예제에서는 파일 크기를 5MB (5 1024 1024 byte) 로 제한해두었습니다.

다만 위 설정을 실제로 활용하기 위해선 서버에 uploads 폴더가 꼭 존재해야 합니다.
없다면 직접 만들어주거나, fs 모듈로 서버를 시작할 때 생성하는 방식이 있습니다.

upload.single()

설정이 끝난다면 위에서 선언해준 upload 객체 변수가 생기게 되는데, 이 안에 다양한 종류의 미들웨어가 존재합니다.

파일을 하나만 업로드하는 경우에는 single 미들웨어를 사용합니다.

  • upload 라는 객체는 위에서 multer 설정한 변수
// 단순 웹페이지 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');
})

single 미들웨어를 라우터 미들웨어 앞에 넣어두면 multer 설정에 따라 파일 업로드 후 req.fiile 객체가 생성됩니다.
인수는 input 태그의 name이나 폼 데이터의 키와 일치하게 넣으면 됩니다.
업로드가 성공하면 결과는 req.file 객체 안에 들어갑니다.
req.body에는 파일이 아닌, input 텍스트 데이터인 title이 들어가있습니다.
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을 씁니다.

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

input태그 여러개(다중)파일 선택하기
이 경우 미들웨어는 single 대신 array로 교체하면 됩니다.
이때 업로드 정보들은 배열로 저장되게 됩니다.

app.post('/upload', upload.array('many'), (req, res) => {
    console.log(req.files); // 업로드 결과도 req.file 대신 req.files 배열에 들어간다
    res.send('ok');
});

upload.field()

한번에 파일을 여러 개 업로드하는게 아닌, 따로따로 업로드를 여러개 한다면,
즉, input 태그나 폼 데이터의 키가 다른 경우엔 fields 미들웨어를 사용합니다.
예를 들어 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>

이 경우엔 fields 미들웨어를 사용하고, 인수로 input 태그들의 name들을 각각 적습니다.
name뿐만 아니라 limits도 설정할수있는데, 이미지를 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()로 데이터를 보낼때도 있기 때문입니다.
그 경우 none 미들웨어를 사용합니다.
파일은 없지만 멀티파트 형식이기 때문에 함수가 따로 존재하는 것입니다.

app.post('/upload', upload.none(), (req, res) => {
    console.log(req.body.title); // 이 경우 파일을 업로드하지 않으므로 req.body만 존재한다.
    res.send('ok');
});




참고
https://inpa.tistory.com/entry/EXPRESS-%F0%9F%93%9A-multer-%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4

profile
선명한 기억보다 흐릿한 메모

0개의 댓글