Node.js 로 파일 업로드와 관련한 내용을 찾아보았다. 노드로 백엔드 구축하는데 이번이 처음이기에 Java로 구축한 부분과 사뭇 많이 달랐다. 간결하고 속도가 빠르다고 느껴졌다... 그냥 느낌인가??
Multer 에 대해 알아보도록 하자
Multer
Multer는 Node.js 환경에서 파일 업로드를 처리하기 위한 미들웨어야. 주로 Express 프레임워크와 함께 사용되며, 사용자가 서버에 파일을 업로드할 수 있도록 도와주는 역할을 해. Multer는 multipart/form-data 형식의 요청을 처리하고, 업로드된 파일을 디스크에 저장하거나 메모리에 유지할 수 있도록 설정할 수 있어.
주요 기능:
- 파일 저장: 사용자가 업로드한 파일을 서버의 특정 디렉토리에 저장할 수 있어.
- 파일 이름 설정: 업로드된 파일의 이름을 변경하거나, 고유한 이름으로 저장할 수 있어.
- 파일 크기 및 형식 제한: 업로드할 수 있는 파일의 크기와 형식을 제한하여 보안을 강화할 수 있어.
- 다중 파일 업로드 지원: 한 번의 요청으로 여러 개의 파일을 업로드할 수 있어.
사용 예:
const multer = require('multer');
// 파일 저장소 설정
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/'); // 파일 저장 경로
},
filename: function (req, file, cb) {
cb(null, Date.now() + '-' + file.originalname); // 파일 이름 설정
}
});
// Multer 인스턴스 생성
const upload = multer({ storage: storage });
그럼 Multer 를 사용하기 위한 환경설정을 알아보자
환경설정
1. 필요한 패키지 설치
아래 명령어로 Express, Multer 패키지를 설치해 줘.
npm init -y # (프로젝트 초기화)
npm install express multer
2. 기본 파일 업로드 코드
아래는 Multer를 사용하여 파일을 업로드하는 간단한 Express 서버 코드야.
const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();
const port = 3000;
// 업로드된 파일을 저장할 디렉토리 설정
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/'); // 파일 저장 경로
},
filename: function (req, file, cb) {
cb(null, Date.now() + path.extname(file.originalname)); // 파일명 설정 (현재시간 + 확장자)
}
});
// 파일 업로드 설정
const upload = multer({ storage: storage });
// 정적 파일 제공 (업로드된 파일 확인용)
app.use('/uploads', express.static('uploads'));
// 단일 파일 업로드 라우트
app.post('/upload', upload.single('file'), (req, res) => {
if (!req.file) {
return res.status(400).send('파일이 업로드되지 않았습니다.');
}
res.send(`파일 업로드 성공! 파일 경로: /uploads/${req.file.filename}`);
});
// 서버 실행
app.listen(port, () => {
console.log(`서버 실행 중: http://localhost:${port}`);
});
3. 파일 업로드 테스트 방법
① "uploads" 폴더 생성
업로드된 파일을 저장할 uploads 폴더를 생성해야 해.
mkdir uploads
② Postman 또는 cURL을 사용해서 업로드 요청 보내기
- Postman을 열고 POST 요청을 보낸다.
- URL: http://localhost:3000/upload
- Body → form-data 선택
- Key: file (input name과 동일해야 함)
- Value: 업로드할 파일 선택
또는 cURL을 사용하여 테스트할 수도 있어.
curl -X POST -F "file=@test.jpg" http://localhost:3000/upload
4. 다중 파일 업로드
upload.single('file') 대신 upload.array('files', 5)를 사용하면 한 번에 여러 개의 파일을 업로드할 수 있어.
app.post('/uploads', upload.array('files', 5), (req, res) => {
if (!req.files || req.files.length === 0) {
return res.status(400).send('파일이 업로드되지 않았습니다.');
}
res.send(req.files.map(file => `/uploads/${file.filename}`));
});
5. 파일 크기 제한 & 필터링
보안 및 서버 보호를 위해 파일 크기와 확장자를 제한하는 것이 중요해.
const upload = multer({
storage: storage,
limits: { fileSize: 5 * 1024 * 1024 }, // 파일 크기 제한 (5MB)
fileFilter: function (req, file, cb) {
const fileTypes = /jpeg|jpg|png|gif/;
const extName = fileTypes.test(path.extname(file.originalname).toLowerCase());
const mimeType = fileTypes.test(file.mimetype);
if (extName && mimeType) {
return cb(null, true);
} else {
return cb(new Error('이미지 파일만 업로드 가능합니다!'));
}
}
});
이렇게 하면 5MB 이하의 JPG, PNG, GIF 파일만 업로드 가능하도록 제한할 수 있어.
추가적인 방법
const express = require('express');
const router = express.Router();
const multer = require("multer");
const path = require("path");
//diskStorage 엔진으로 파일저장경로와 파일명을 세팅한다.
let storage = multer.diskStorage({ //multer disk storage settings
destination: function(req, file, callback) {
callback(null, "uploads/")
},
filename: function(req, file, callback) {
let extension = path.extname(file.originalname);
let basename = path.basename(file.originalname, extension);
callback(null, basename + "-" + Date.now() + extension);
}
});
//특정 파일형식만 저장하기 위해서는 fileFilter함수를 사용한다.
const upload = multer({ //multer settings
storage: storage,
fileFilter: function(req, file, callback) {
var ext = path.extname(file.originalname);
if (ext !== '.xlsx' && ext !== '.pdf' && ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
return callback(new Error('Only .xlsx .pdf .png, .jpg .gif and .jpeg format allowed!'))
}
callback(null, true)
},
}).any(); //.any()는 전달받는 모든 파일을 받는다. 파일배열은 req.files에 저장되어 있다.
router.post('/files', (req, res, next) => {
const reqFiles = [];
try {
upload(req, res, function(err) {
if (err) {
return res.status(400).send({ //에러발생하면, 에러 메시지와 빈 파일명 array를 return한다.
message: err.message,
files: reqFiles
});
}
for (var i = 0; i < req.files.length; i++) { //저장된 파일명을 차례로 push한다.
reqFiles.push(req.files[i].filename)
}
res.status(200).send({ //저장 성공 시, 저장성공 메시지와 저장된 파일명 array를 return한다.
message: "Uploaded the file successfully",
files: reqFiles
});
})
} catch (err) {
console.log(err);
res.status(500).send({
message: `Could not upload the file: ${err}`,
files: reqFiles
});
}
});
module.exports = router;
import axios from 'axios';
const upload = (file) => {
let formData = new FormData();
for (const key of Object.keys(file)) {
formData.append('file', file[key]);
}
//formData.append("file", file);
return axios.post("/api/upload/files", formData, {
headers: {
"Content-Type": "multipart/form-data",
}
});
};
export default {
upload
};
위와 같이 Node.js 를 타입스크립트로 전환한다음 사용해서 파일 업로드에 잘 되도록 해보니 잘 되었다.
위와 같은 상세한 코드로 같이 Node.js 에서 파일 업로드를 시도해보자 .

그리고 나는 스프링부트에서 사용하다 보니 Node.js 에서 하는 방법을 찾아보고 싶었는데 드디어 찾아서 적용했다는 생각이 들었다. 밑에는 내가 했던 스프링부트 코드이다.
생각보다 Springboot 보단 복잡하다는 생각을 했다
public void saveImage(MultipartFile file, String uuid, String user_uuid) throws Exception {
String filename = uuid + "_" + user_uuid + "_" + file.getOriginalFilename();
if (filename == null || filename.isEmpty()) {
log.error("[saveImage] => Filename is empty");
}
if (filename.contains("_thumbnail")) {
File destinationFile = new File(uploadDir + "/" + URLs.thumbnail + "/" + filename);
if (!destinationFile.getParentFile().exists())
destinationFile.getParentFile().mkdirs();
file.transferTo(destinationFile);
} else {
File destinationFile = new File(uploadDir + "/" + URLs.image + "/" + filename);
if (!destinationFile.getParentFile().exists())
destinationFile.getParentFile().mkdirs();
file.transferTo(destinationFile);
}
int res = fileMapper.insertFile(uuid, user_uuid, filename);
log.info("[saveImage] => success cnt {}", res);
}
이게 Springboot 에서 파일 다운로드이고 내가 사용중에 있다.
import multer from "multer";
import fs from "fs";
import { uploadDir } from "./Constants";
import uuid from "react-uuid";
/* 파일생성 */
fs.readdir(uploadDir, (error) => {
// uploads 폴더 없으면 생성
if (error) {
fs.mkdirSync(uploadDir);
}
});
const diskStorage = multer.diskStorage({
// 목적지 주소
destination: function (req, file, callback) {
callback(null, uploadDir);
},
// 저장될 파일 이름
filename: function (req, file, callback) {
callback(null, uuid());
},
});
const upload = multer({
storage: diskStorage,
limits: {
files: 5,
fileSize: 1024 * 1024 * 1024,
},
});
export default upload;
이게 Node 에서 사용중인 Multer 이다
개인적으로 너무 간단하다... Node 부분이..
'개발 > Node.js' 카테고리의 다른 글
Node_ Npm 관리 (0) | 2025.02.27 |
---|