[node.js] node.js의 파일 전송
![[node.js] node.js의 파일 전송](/assets/img/web/nodejs/logo.png)
multer 모듈을 사용해 node.js에서 파일을 전송하는 방법을 살펴봅니다.
- 1. multer 모듈 설치
- 2. app.js 생성
- 3. index.ejs - 싱글 파일 업로드 폼 작성
- 4. app.js - multer 설정
- 5. index 화면 - 파일 업로드
- 6. index 화면 - 파일 업로드 결과
- 7. app.js - multer 세부 설정
- 8. index 화면 - 파일 업로드 결과
- 9. index.ejs - 멀티 파일 업로드 폼 작성
- 10. app.js - multer 멀티 파일 설정
- 11. index 화면 - 멀티 파일 업로드 1
- 12. index 화면 - 멀티 파일 업로드 1 결과
- 13. index 화면 - 멀티 파일 업로드 2
- 14. index 화면 - 멀티 파일 업로드 2 결과
- 15. index.ejs - 동적 파일 업로드 폼 작성
- 16. app.js - multer 동적 파일 설정
- 17. index 화면 - 동적 파일 업로드
- 18. index 화면 - 동적 파일 업로드 결과 1
- 19. index 화면 - 동적 파일 업로드 결과 2
앞서 post 방식의 요청을 처리할 때 body-parser를 사용했습니다. body-parser는 이미지, 동영상, 파일 등의 멀티파트 데이터는 처리할 수 없습니다. 따라서 멀티파트 데이터를 처리하기 위해서 multer 모듈을 사용합니다.
1. multer 모듈 설치
‘npm i multer’ 명령어를 사용해 multer 모듈을 설치합니다. express와 ejs도 함께 설치합니다.
2. app.js 생성
app.js를 생성해 서버의 기본 설정을 작성합니다.
설치한 모듈을 불러오고 뷰 엔진을 지정한 뒤 기본 주소로 접근시 index.ejs로 매핑되도록 코드를 작성합니다.
3. index.ejs - 싱글 파일 업로드 폼 작성
index.ejs에 파일 업로드 폼을 작성합니다.
submit시 post 방식으로 ‘/upload’로 이동하도록 합니다. 또한 enctype 속성의 값을 ‘mulitpart/form-data’로 지정합니다.
이 때 요청을 보내는 파일의 데이터가 name 속성으로 전달됩니다.
4. app.js - multer 설정
index.ejs의 폼에서 전송한 요청을 받을 수 있도록 app.js에 코드를 작성합니다.
이 때 upload 객체에 multer에 대한 설정을 작성합니다. dest란 요청으로 받은 파일을 저장할 경로를 지정할 때 사용합니다.
multer의 설정을 담은 upload 객체를 post 요청에 응답할 때 사용합니다. app.post()의 두 번째 매개변수로 upload 객체를 사용하였고 이제 req.file을 통해 요청으로 받은 파일의 정보를 확인할 수 있습니다.
upload.single()의 매개변수에 폼에서 전송하는 파일의 name속성의 값으로 정확하게 적어야 합니다.
5. index 화면 - 파일 업로드
브라우저에서 업로드할 파일을 선택한 뒤 업로드 버튼을 클릭합니다.
6. index 화면 - 파일 업로드 결과
업로드 버튼을 클릭한 뒤 프로젝트를 살펴보면 uploads 폴더가 생성된 것을 확인할 수 있습니다. 해당 폴더에는 클라이언트가 업로드한 파일이 확장자 없이 저장되어있습니다. 때문에 직접 jpeg 확장자를 달아준 뒤 확인해보면 정상적으로 업로드된 이미지를 확인할 수 있습니다.
7. app.js - multer 세부 설정
multer의 설정을 작성할 때 단순히 dest만 지정하는 것이 아닌 여러 속성을 지정할 수 있습니다. 위 코드를 살펴보면 uploadDetail 객체에 다양한 multer 설정을 하고있는 것을 확인할 수 있습니다.
크게 storage와 limits 두 가지로 속성이 있고 storage에는 destination과 filename 두 가지 속성이 있습니다.
먼저 storage의 destination은 위의 dest와 마찬가지로 파일의 저장 경로를 의미합니다. filename은 파일을 destination에 저장할 때 이름을 의미합니다. path.extname()은 파일의 확장자를 추출하며 done()에 최종적으로 저장할 이름을 적습니다. 업로드된 파일은 ‘원본파일명 + 현재시각 + 확장자’로 저장됩니다.
다음으로 limits의 경우 저장되는 파일의 크기를 제한합니다. 1024의 경우 1KB이고 1024 * 1024는 1MB입니다.
app.post()에서 upload 객체가 아닌 uploadDetail 객체를 사용하도록 작성합니다.
8. index 화면 - 파일 업로드 결과
다시 프로젝트를 실행한 뒤 파일을 업로드 할 경우 파일의 이름이 설정한대로 저장된 것을 확인할 수 있습니다.
9. index.ejs - 멀티 파일 업로드 폼 작성
이제 하나의 파일이 아닌 여러 파일을 업로드하는 방법을 살펴봅니다.
index.ejs에 위 그림과 같은 폼 두개를 생성합니다. 왼쪽의 폼은 하나의 파일 선택 버튼에 여러 파일을, 오른쪽의 폼은 두 개의 파일 선택 버튼에 두 장의 파일을 전송하도록 작성합니다. 각각의 폼은 ‘/upload/array’, ‘/upload/fileds’로 post 요청을 전송합니다.
10. app.js - multer 멀티 파일 설정
app.js에 각각의 post 요청을 처리하도록 코드를 작성합니다.
‘/upload/array’의 경우 uploadDetail.array()를, ‘/upload/fileds’의 경우 uploadDetail.fileds()를 매개변수로 사용합니다.
11. index 화면 - 멀티 파일 업로드 1
화면의 왼쪽 폼에서 먼저 업로드를 수행합니다.
왼쪽 폼은 하나의 파일 선택에서 여러 파일을 고릅니다.
12. index 화면 - 멀티 파일 업로드 1 결과
업로드 결과 서버에 정상적으로 저장되는 것과 파일들이 배열로 들어오는 것을 확인할 수 있습니다.
13. index 화면 - 멀티 파일 업로드 2
화면의 오른쪽 폼에서 업로드를 수행합니다.
오른쪽 폼은 두 개의 파일 선택에 각각 파일을 고른 뒤 업로드합니다.
14. index 화면 - 멀티 파일 업로드 2 결과
업로드 결과 userFile1과 useFile2에 파일의 정보가 담겨저 오는 것을 확인할 수 있습니다.
15. index.ejs - 동적 파일 업로드 폼 작성
동적으로 폼을 전송하지 않고 기존의 폼으로 전송하는 경우 강제로 새로고침이 되는 단점이 존재합니다. 때문에 axios를 사용해 동적으로 파일을 전송하는 법을 살펴봅니다.
동적으로 파일을 업로드하는 폼은 위의 코드와 같습니다. 그림에는 나오지 않으나 cdn을 작성한 상태입니다.
버튼을 클릭하면 upload()가 실행되며 formData를 생성한 뒤 파일의 정보를 formData에 담습니다. 해당 formData를 post 방식으로 ‘/upload/dynamic’에 전송합니다.
요청에 대한 응답이 올 경우 해당 응답에서 필요한 데이터를 추출해 resultBox div에 innerHTML을 통해 이미지가 추가되도록 작성합니다.
16. app.js - multer 동적 파일 설정
app.post()의 경우 res.send()로 서버에 업로드된 파일의 정보를 다시 보내주도록 작성합니다.
17. index 화면 - 동적 파일 업로드
브라우저에서 파일을 업로드합니다.
18. index 화면 - 동적 파일 업로드 결과 1
업로드 결과 서버에 정상적으로 저장된 것을 확인할 수 있습니다.
19. index 화면 - 동적 파일 업로드 결과 2
또한 log를 통해 업로드된 파일의 정보를 정상적으로 응답받은 것을 확인할 수 있고 화면에 이미지가 출력되는 것을 확인할 수 있습니다.