multer 미들웨어 정리
multer 란
node.js에서 파일 업로드를 제어하는 미들웨어
multer 설치
npm i multer
multer 사용
multer 미들웨어는 이미지를 업로드 하는 라우터에 연결하여 사용할 수 있습니다.
아래는 예시입니다.
1
2
3
4
5
6
7
8
9
10
11
const express = require('express');
const multer = require('multer');
const router = express.Router();
const upload = multer(/*옵션(선택)*/);
router.post('/img',upload.single('img'),(req,res,next)=>{
// 생략
// req.file 에 업로드된 파일 정보 저장
})
위의 예시에서는 multer를 사용하여 img 라는 이름의 파일 하나만 받도록 제어하는 예시입니다. 가장 기본적인 형태입니다.
어떤 파일을, 몇 개나 받을지를 제어하는 부분은 후술하겠습니다.
req.file
multer 를 사용하여 파일 업로드를 제어하는 미들웨어에서는 req.file
에 업로드된 파일의 정보가 저장됩니다.
Key | 설명 |
---|---|
fieldName | 폼에 정의된 필드 명 (HTML에서의 name 속성의 값과 동일) |
originalName | 파일 명 |
encoding | 파일 인코딩 타입 |
mimetype | 파일 Mime 타입 |
size | 파일 바이트 사이즈 |
destination | 파일이 저장된 폴더 |
filename | destination에 저장된 파일 명 |
path | 업로드 된 파일의 전체 경로 |
buffer | 전체 파일의 buffer |
multer 옵션
multer 객체에는 옵션을 사용하여 개발 환경에 알맞게 생성하여 사용할 수 있습니다.
key | 설명 |
---|---|
dest | 파일이 저장될 경로. 파일명은 임의 생성된 파일명 사용 |
storage | 파일이 저장될 경로. 파일명/경로를 설정한 값 사용 |
fileFilter | 파일이 저장되기 전에 필터를 통한 저장 제어 함수 |
limits | 파일의 크기 제한 |
preservePath | 파일명 대신 파일 전체 경로를 이름으로 사용할지 여부 |
dest
파일이 저장될 경로를 명시합니다.
저장되는 파일명은 multer 가 랜덤 생성한 문자열을 사용합니다.
storage
파일이 저장될 경로와 파일명을 설정합니다.
stroage는 StorageEngine를 타입으로 받으며,
이는 multer의 diskStorage() 를 사용하여 생성할 수 있습니다.
참고로 diskStorage() 에 사용되는 옵션에는 destination 과 filename이 있는데 destination은 string 을 사용하는 옵션으로도 사용할 수 있습니다. (인터페이스 참고) 파일이 업로드 될 디렉토리가 고정적이라면 문자열을 사용할 수 도 있습니다.
아래는 예시 코드 입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const express = require('express');
const multer = require('multer');
const router = express.Router();
const storage = multer.diskStorage({
destination(req,file,cb){
cb(null,'uploads/');
},
// destination 옵션은 string 을 파라미터로 받으며 파일이 업로드 될 디렉토리가 고정적이라면 아래와 같이 사용하여도 무방하다
//destination:'uploads/',
filename(req,file,cb){
const ext = path.extname(file.originalname);
cb(null,path.basename(file.originalname,ext)+Date.now()+ext);
}
})
const upload = multer({storage:storage});
router.post('/img',upload.single('img'),(req,res,next)=>{/*생략*/})
fileFilter
파일이 업로드 되기 전에 어떠한 파일을 허용할지 확인하는 함수형 옵션입니다.
(요청, 파일, 콜백 함수)
구조의 파라미터를 사용합니다.
콜백 함수는 다음의 인터페이스 구조를 가집니다.
1
2
3
4
interface FileFilterCallback {
(error: Error): void;
(error: null, acceptFile: boolean): void;
}
콜백 함수의 첫 번째로 에러를 전달하고 두 번째로 파일 업로드 허용 여부를 boolean 으로 전달합니다.
예시 코드)
1
2
3
4
5
6
7
8
9
multer({
fileFilter(req,file,cb){
/* 파일 유효성 검증 로직
예시) text 파일 내에 특정 문자가 존재하는지 여부
파일의 확장자, MIME 타입 검증 등
*/
cb(null,true); // 업로드 허용 시
}
})
limits
파일의 사이즈를 제한합니다.
바이트(Byte)를 기준으로 합니다.
limits 의 옵션
| key | 설명 | 기본값 | | ————- | ——————————————– | ——— | | fieldNameSize | 필드명 최대 값 | 100 bytes | | fieldSize | 필드값 사이즈 최대 값 | 1MB | | fields | 파일형식이 아닌 필드의 최대 개수 | 무제한 | | fileSize | multipart 형식 폼에서 최대 파일 사이즈(bytes) | 무제한 | | files | multipart 형식 폼에서 파일 필드의 최대 개수(파일만) | 무제한 | | parts | multipart 형식 폼에서 파일과 필드의 최대 개수 (파일 + 필드) | 무제한 | | headerPairs | multipart 형식 폼에서 파싱할 헤더의 key=>value 쌍의 최대 개수 | 2000 | 여기서 parts
와 files
의 설명이 모호하여 했갈릴 수 있습니다.
- files : 업로드할 수 있는 파일의 갯수
- 예시 )
files : 5
인 경우 5개의 파일만 허용
- 예시 )
- parts : 업로드 할 수 있는 파일의 갯수 + formData 내의 필드 갯수
- 예시)
parts : 5
인 경우 사용자이름, 본문 + 3개의 이미지 와 같이 파일을 제외한 필드 + 파일 을 포함
- 예시)
예시 코드)
1
2
3
4
5
multer({
limits:50*1024*1024 // 파일의 크기를 50메가 바이트까지로 제한,
parts : 10, // 총 필드+파일의 수는 10개로 제한
files : 3, // 그 중 파일은 최대 3개로 제한
})
preservePath
업로드된 파일명을 경로를 포함한 값으로 사용할지 여부 입니다.
공식 문서나 국내외의 블로그에서 해당 옵션 사용에 관한 내용을 확인해보고자 했지만 내용이 확인되지 않았습니다.
일반적인 웹에서 input을 통해 파일을 업로드 하는 경우 에는 파일의 경로가 전달되는 경우가 없기 때문에 어느 상황에 유효한지에 대해서는 좀 더 공부해봐야겠습니다.
업로드 제어
위의 다양한 옵션을 통해 상황에 알맞은 multer 를 생성했다면 이를 통해 파일의 업로드를 제어할 수 있습니다.
제어를 통해 다음 미들웨어로 전달된 파일의 정보는 요청 객체(request) 에서 확인할 수 있습니다.
single(필드명)
필드명으로 명시한 파일을 하나만 받습니다.
전달된 파일은 req.file
에서 확인할 수 있습니다.
array(필드명[, 총갯수])
필드명에 해당하는 파일을 배열로 받습니다. 선택적 옵션으로 전달되는 배열의 갯수를 사용할 수 있으며 명시한 값만큼의 파일만 받습니다.
fields()
와 다른 점은 하나의 필드를 받는 다는 점 입니다.
전달된 파일 정보는 req.files
에서 확인할 수 있습니다.
예시 코드)
1
2
3
// 생략
const upload = multer({/*옵션*/})
router.post('/img',upload.array('img',10),(req,res,next)=>{/*생략*/})
위와 같은 경우 name의 값이 img 인 파일이 복수로 전달될 수 있으며 최대 10개 까지를 허용하는 예시입니다.
fields(field)
array()
와 유사합니다. 하지만 복수의 필드를 받을 수 있습니다.
field
는 name과 maxCount 를 포함하는 객체입니다. maxCount는 선택 사항입니다.
전달된 파일 정보는 req.files
에서 확인할 수 있습니다.
예시 코드)
1
2
3
4
5
6
7
8
9
10
11
12
13
// 생략
const upload = multer({/*옵션*/})
router.post(
'/img',
upload.fields(
{
name:'cat',
maxCount:2
},{
name:'dog'
}
),
(req,res,next)=>{/*생략*/})
name의 값이 cat 인 파일을 최대 2개까지 허용하며, name의 값이 dog인 파일을 제한 없이 허용하는 예시 입니다.
none()
파일을 업로드를 허용하지 않습니다.
any()
모든 파일을 허용합니다.
전달된 파일 정보는 req.files
에서 확인할 수 있습니다.
참조 : https://github.com/expressjs/multer/blob/master/doc/README-ko.md