즐코

Nodejs에서 파일 업로드 구현 - multer 라이브러리 사용 본문

NodeJS

Nodejs에서 파일 업로드 구현 - multer 라이브러리 사용

YJLEE_KR 2022. 3. 17. 00:52

multer 라이브러리 사용법

- 하나의 파일 업로드

- 다수의 파일 업로드

- file input이 여러개일때 파일 업로드

- 비동기 파일 업로드

 

파일 업로드도 텍스트를 보내주는 것과 똑같다.

컴퓨터는 0,1밖에 모르니 파일,사진을 보내도 텍스트 파일로 본다.

 

파일 업로드에는 multer 라이브러리를 사용하는 걸 배웠다. 

 

npm install multer

const multer = require('multer')

 

우선 파일을 업로드할 html파일을 작성해보자.

 

늘 하듯 form 형태로 보낸다. 다만, 여기서 이전과 다른게 있다면,   enctype 이다.

아래와 같이 3가지 옵션이 있는데, default값이 application/x-www-form-urlencoded여서 이전엔 이 부분에 대해서 신경쓰지 않았었다.

근데, 파일 업로드 할땐 enctype = "multipart/form-data' 여야한다.

 

input type=file 

 

우린 클라이언트가 요청을 보내면 요청 바디에 있는 내용들을 req.body로 갖고 온다.

근데 이때, express가 알아서 body안의 데이터를 파악해가지고 해석해주지 않았다.

우리가 express가 해석할 수 있게끔 req.body의 content-type에 따라 미들웨어를 넣어줬었다.

 

요청 바디의 데이터 타입 (Content-type) express 의 req.body 해석 미들웨어
application/x-www-form-urlencoded app.use(express.urlencoded({extended:true}))
application/json app.use(express.json())
multipart/form-data multer 라이브러리 사용 + 각 라우터마다 미들웨어 넣어줘야함

 

우선 multer 객체를 만들어줘야한다.

 

multer 속 객체 안에는

1- storage (저장 공간에 대한 디테일), 2- limits(파일사이즈 관련 디테일)이 들어간다. 

storage의 속성값으로 multer.diskStorage() 라는 메소드를 넣어주는데, 그 안에 인자로 객체를 넣어준다.

그 인자로 들어가는 객체는 콜백함수 done을 리턴하는  destination filename이라는 속성이 있다. 

각각 서버쪽 파일 저장 장소와 파일저장명을 설정해주는 거다. 

 

 

 

이제 이 만들어진 upload (multer) 객체를 이용하여 미들웨어 내에 넣어주고, 파일 업로드를 위한 라우터 작성을 해주면 된다.

 

다른 데이터 타입들은 app.use()를 썼지만, 이 multer는 각각의 라우터 상에 미들웨어로 넣어줘야 한다.

 

 


1/ 파일을 한 번에 하나만 업로드 할 때

 

미들웨어

upload.single('input의 name넣어주기')

upload.single('upload') : html 상에서 파일 업로드 input의 name을 upload로 정했기때문에 그걸 인자로 넣어준 것   

 

req.file 출력해보면, 

아래와 같이 파일의 정보를 담은 객체가 리턴되는 걸 확인할 수 있다.

 

그리고 실제로 multer객체를 만들때 destination의 done 콜백함수에 넣어주었던 디렉토리 경로에 파일이 업로드 되는 것도 확인할 수 있었다.


 

2/ 파일을 한 번에 여러개 업로드 할 때

 

미들웨어

upload.array('input의 name넣어주기')

upload.array('upload')

 

 

HTML 수정 필요

이때, 다중 업로드는 HTML 파일도 수정해줘야한다.

input 엘리먼트에 multiple 속성값을 추가해야한다.

 

 

브라우저가 선택한 파일 개수대로 화면 상에 나타내준다.

이 때 파일 데이터를 확인하고 싶다면, req.file이 아니라, req.files로 데이터를 가져와야한다.


 

3/ 파일 업로드 input이 여러개라면?

 

 

미들웨어

upload.fields([{name:'각 인풋 name값'},{name:'각 인풋 name값'}])

{name:name값}을 가진 배열이 인자로 들어간다

 

 

req.files.name값 으로 출력하면 배열 형태로 파일 정보가 출력됨을 확인할 수 있다.

 


 

4/ 비동기로 파일 업로드 처리해보기

 

새로 배운 사실

 

1- 부모안의 자식 노드는 e.target.name명으로 pick 할 수 있다.

현재 이벤트가 일어나는 곳은 form엘리먼트이고 e.target을 찍어보면 당연히 form 엘리먼트가 나온다

 

2- 파일업로드 시 input type=file의 속성값 files를 출력해보면, FileList라는 유사 배열 객체가 나온다.

   아래와 같이 업로드한 파일에 대한 데이터를 담았다.

 

 

3. FormData()라는 js 내장 객체

let formData = new FormData() 하면 빈 FormData객체를 생성한 것 

- FormData().append 메소드

  FormData().append(key값,value값) => key/value 쌍을 추가할 수 있다.

- file객체 안의 내용을 enctype타입으로 인코딩해준다.

 

마지막으로 이렇게 새로 만들어준 formData를 axios로 백서버에 보내주고 응답을 받으면 끝. 

 

 

Comments