생각보다 사용방법이 어렵다 느껴 간단하게 정리해보고자 합니다.
Multer는 파일 업로드를 처리하는 미들웨어 입니다.
특히 multipart/form-data를 처리하는데 사용하고, 파일을 디스크 또는 메모리에 저장할 수 있습니다.
기본개념
multer를 사용하면 클라이언트라 form-data로 업로드한 파일을 서버에서 처리하고 저장할 수 있습니다.
storage: 파일 저장 방식(디스크 저장 or 메모리 저장)
destination : 파일이 저장될 폴더 지정
filename : 저장될 파일명 지정 (이름 충돌 방지)
limits : 파일 크기 제한 설정 가능
fileFilter : 특정 파일만 허용 가능 ( ex : 이미지 파일만 허용)
const upload = multer({
storage: multer.diskStorage({
destination(req, file, cb) {
cb(null, "uploads/");
},
filename(req, file, cb) {
const ext = path.extname(file.originalname); // 이미지.png => 이미지 (날짜).png 이름중복방지
cb(null, path.basename(file.originalname, ext) + Date.now() + ext);
//기존 파일명 + 현재 시간(중복 방지) + 확장자 형태로 저장
},
}),
});
- 파일 저장위치 : uploads/ 폴더에 저장
- 파일 이름 처리 :
- path.extname(file.originalname) -> 파일 확장자 추출
- path.basename(file.originalname, ext) -> 확장자를 제외한 파일 이름 추출
- Data.now() 를 추가하여 파일 이름이 중복되지 않도록 합니다
(여러 사람이 이용하다보면 파일 이름 중복의 가능성이 있습니다)
- (ex : image.png -> image62375637545.png) 의 형식으로 저장됩니다.
Multer의 활용
1. 파일 업로드 (single())
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="image" />
<button type="submit">업로드</button>
</form>
app.post("/upload", upload.single("image"), (req, res) => {
res.json({ file: req.file }); // 업로드된 파일 정보 응답
});
클라이언트가 image라는 이름으로 1개의 파일을 업로드하면 저장됨. (req.file 에 업로드된 파일 정보가 저장됩니다.)
* 여기서 "image"는 form애 있는 input의 name 을 의미합니다.
2. 다수의 파일 업로드( array() )
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="images" multiple />
<button type="submit">업로드</button>
</form>
form은 위와 동일 input의 name이 image => images로 변경
app.post("/upload-multiple", upload.array("images", 5), (req, res) => {
res.json({ files: req.files });
});
images 라는 필드 이름으로 최대 5개의 파일을 업로드 가능
3. 다수의 필드로 파일 업로드 ( fields() )
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="profile" />
<input type="file" name="cover" />
<button type="submit">업로드</button>
</form>
app.post(
"/upload-fields",
upload.fields([{ name: "profile", maxCount: 1 }, { name: "cover", maxCount: 5 }]),
(req, res) => {
res.json({ profile: req.files.profile, gallery: req.files.cover });
}
);
profile 최대 업로드 : 1, cover 최대 업로드: 5
4. 파일 필터링 ( 이미지만 허용하는 예시)
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="image" accept="image/*" required />
<button type="submit">업로드</button>
</form>
const upload = multer({
storage: multer.diskStorage({
destination(req, file, cb) {
cb(null, "uploads/");
},
filename(req, file, cb) {
const ext = path.extname(file.originalname);
cb(null, path.basename(file.originalname, ext) + Date.now() + ext);
},
}),
fileFilter(req, file, cb) {
if (!file.mimetype.startsWith("image/")) {
return cb(new Error("이미지 파일만 업로드 가능합니다."), false);
}
cb(null, true);
},
});
accept = "image/*" : 이미지 파일만 선택 가능하도록 제한
required : 파일을 선택하지 않으면 제출 불가능
Multer의 파일 처리과정
- 클라이언트가 form-data로 요청을 보냅니다(POST /upload)
- Multer가 요청을 가로채고 파일을 uploads/ 에 저장합니다 (uploads/ 는 예시)
- 파일 정보가 req.file 또는 req.files에 저장됩니다.
- 라우터에서 req.file을 이용해 응답하거나, db에 저장합니다.