✅ multer 사용계기
React, Node.js로 진행 중인 프로젝트에서, 파일 업로드 기능을 구현하게 되었다. 사용자가 업로드하고자 하는 파일을 선택하여 드롭다운하면 해당 파일이 서버에 저장되도록 구현할 것이다.
✅ 사용이유
일반적으로 클라이언트에서 서버로 폼 데이터(form data)가 전송될 때 해당 데이터는 인코딩되어 전송된다. 이러한 방식은 JSON 형식의 데이터를 전송하는 것에는 어려움이 없으나, 파일 자체를 전송하려 할 때는 생각한 것처럼 전송되지 않는다. 파일을 무작정 body에 넣어서 POST 요청을 보냈으나 서버에서는 body 안에 있어야 할 파일을 가져오지 못했다.. 이러한 상황에서 파일을 온전하게 전송하기 위해서는 파일을 입력하는 form 태그의 encType 속성을 multipart/form-data로 바꿔줘야 한다. encType 속성은 입력된 데이터가 서버에 전송될 때 인코딩되는 방식을 결정한다. 디폴트는 application/x-www-form-urlencoded인데, 이 경우 모든 문자를 인코딩하여 전송하게 되며, 위에서 언급한 multipart/form-data는 모든 문자를 인코딩하지 않고 전송한다. mutler가 바로 이 multipart/form-data를 다루기 위한 node.js의 미들웨어다.
✅ 구현
1. 파일 업로드를 위한 form 구현 (React)
사용자가 업로드할 파일을 선택하고 전송할 수 있도록 form을 만들어준다.
function VideoUploadPage() {
const handleDrop = (files) => {
let formData = new FormData();
const config = {
header: { "content-type": "multipart/form-data" },
};
formData.append("file", files[0]);
axios.post("/api/video/uploadfiles", formData, config).then((res) => {
if (res.data.success) {
console.log(res.data);
} else {
alert("비디오 업로드를 실패했습니다.");
}
});
};
return (
<form>
<Dropzone onDrop={handleDrop}>
```생략```
</Dropzone>
</form>
)
2. multer를 이용하여 전송받은 파일 저장하는 api 구현 (Node.js)
일단 api를 만들 node.js 프로젝트에 multer를 설치한다.
npm i multer
가장 기본적인 형태의 multer 사용이다. destination으로 경로를 지정해주었고 filename으로 파일명을 지정해 주었다. mime type으로 타입을 체크하여 내가 원하는 비디오 타입만 필터링되게 설정해 줬다. 이로 인해 전송받은 파일은 node.js 내부의 uploads 디렉터리에 저장될 것이고 만약 uploads 디렉터리가 없다면 자동으로 생성이 되어 그 안에 저장될 것이다.
const express = require("express");
const router = express.Router();
const multer = require("multer");
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "uploads/");
},
filename: (req, file, cb) => {
cb(null, `${Date.now()}_${file.originalname}`);
},
});
const fileFilter = (req, file, cb) => {
// mime type 체크하여 원하는 타입만 필터링
if (file.mimetype == "video/mp4") {
cb(null, true);
} else {
cb({ msg: "mp4 파일만 업로드 가능합니다." }, false);
}
};
const upload = multer({ storage: storage, fileFilter: fileFilter }).single(
"file"
);
비디오를 서버에 저장하는 post이다.
router.post("/uploadfiles", (req, res) => {
// 비디오를 서버에 저장한다.
upload(req, res, (err) => {
if (err) {
return res.json({ success: false, err });
}
return res.json({
success: true,
filePath: res.req.file.path,
fileName: res.req.file.filename,
});
});
});
동영상을 드롭다운하면 uploads 파일에 동영상(mp4)이 생긴 것을 볼 수 있다!
VideoUploadPage에서 axios로 응답 받은 내용
'🍞 Back-End > Node.js' 카테고리의 다른 글
[Node.js] 구독하기(팔로우, 팔로워) 기능 (0) | 2022.12.29 |
---|---|
[Node.js] 로그인, 로그아웃, 회원가입 구현 with MongoDB (0) | 2022.12.24 |
[Node.js] methods와 statics 차이 (0) | 2022.12.18 |
[Node.js] 비밀 정보 보호하기 (github에 올리지 않기) (0) | 2022.12.18 |
[Node.js] 개발 서버 실행과 빌드 (2) | 2022.09.30 |