[ 목차 ]
1. 파일 업로드 프론트 엔드에서의 작업
<form action = "/upload" method = "POST" enctype "multipart/form-data">
<input type = 'file' name = 'userfile'/> <br/>
<input type = "text" name = "title" /> <br/> <br/>
<button type = "submit"> 업로드 </button>
</form>
1) form 테그의 enctype 속성으로 "multipart/form-data"를 반드시 설정한다.
- multer 미들웨어의 경우 "multipart/form-data"가 아닌 폼에서는 동작하지 않음.
2. node js 서버에서의 작업 = multer
설치 명령어 : npm install multer
- 파일 업로드를 위해 사용되는 미들웨어로 주로 express를 통해 서버를 구축할 때 많이 사용됨.
1) 파일 업로드 경로 설정
const multer = require('multer');
const upload = multer({
dest : 'uploads/',
});
dest 속성 : 파일을 업로드하고 그 파일이 저장될 경로를 지정하는 속성
2) 하나의 파일을 업로드 할 때?
#. 프론트엔드
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="userfile" />
<input type="text" name="title" /> <br /><br />
<button>업로드</button>
</form>
#. 백엔드
//multer 관련 설정
const multer = require("multer");
const path = require("path"); // 경로 처리를 위한 내장 모듈
const upload = multer({
dest: "uploads/", // dest : 클라이언트가 업로드한 파일을 저장할 서버측 검토
});
app.post("/paractice-POST", upload.single("userfile"), (req, res) => {
console.log(req.file);
res.render("paractice-POST", {
title: "아이디 정보",
userInfo: req.body,
file: req.file, //파일 정보도 넘겨 줘야 함.
});
});
req. file에 대한 정보가 없을 때엔 에러를 발생 시키기에 따로 상황에 따른 router를 따로 두어야 한다.
3) multer - 하나의 요청 안에 여러 개의 파일이 존재할 때
(프론트 엔드)
<h2>Multiple file upload v1</h2>
<p>하나의 인풋에 여러개의 파일을 업로드</p>
<form action="/upload/array" method="post" enctype="multipart/form-data">
<input type="file" name="userfiles" multiple />
타이틀 <input type="text" name="title" /> <br /><br />
<button>업로드</button>
</form>
- 간단하게 file 테그에 multiple 속성을 추가 시켜주면 된다.
(서버 단에서 할 일)
// 2. array() : 여러 파일을 한번에 업로드
//uploadDetall.array("userfiles");
//파일을 업로드 한 후, req.files라는 객체가 생성됨.
app.post("/upload/array", uploadDetail.array("userfiles"), (req, res) => {
console.log(req.files); // [{파일1의 정보}, {파일2의 정보}, {파일3의 정보}, ....]
console.log(req.body); //
res.send("하나의 인풋에 여러 파일 업로드 완료");
});
- 하나의 파일 만 업로드하는 기능인 경우와 달리, req.files에 배열의 형태로 객체로 정보가 담기는 것을 확인할 수 있다.
4) 여러개의 파일을 여러개의 요청으로 보내고 싶을 때
(프론트엔드 단에서 해줘야 할 일)
<h2>Multiple file upload v2</h2>
<p>여러개의 인풋에 각각의 파일을 업로드</p>
<form action="/upload/fields" method="post" enctype="multipart/form-data">
<input type="file" name="userfile1" />
<input type="file" name="userfile2" />
타이틀 <input type="text" name="title" /> <br /><br />
<button>업로드</button>
</form>
- 인풋 테그의 갯수 만큼 파일을 저장하여 처리하는 방식이라고 생각하면 된다.
(백엔드)
app.post(
"/upload/fields",
uploadDetail.fields([{ name: "userfile1" }, { name: "userfile2" }]),
(req, res) => {
console.log(req.files);
console.log(req.body);
res.send("여러 인풋에 각각의 파일 업로드 완료");
}
);
- fields에 들어간 배열 내의 객체 숫자 만큼, input 테그로 받은 파일을 업로드할 수 있다.
5) axios를 사용한 동적 파일 업로드
(프론트 엔드)
<h2>동적 파일 업로드</h2>
<input type="file" name="dynamicUserFile" id="dynamic-file" />
<br />
<button onclick="fileUpload()">업로드</button>
<br />
<!-- 업로드한 이미지를 보여줄 img 테그 요소 -->
<img src="" alt="" />
<script>
function fileUpload() {
//동적 파일 업로드
// js 만으로 폼을 전송
// 파일 데이터를 전송할 떄 FormData 객체를 활용할 것임.
//FormData란?
// form 테그의 데이터를 동적으로 제어할 수 있는 기능
const formData = new FormData();
const file = document.querySelector("#dynamic-file");
console.log(file);
console.log(file.files);
formData.append("dynamicUserFile", file.files[0]);
axios({
method: "post",
url: "dynamicFile",
data: formData,
headers: {
"Content-Type": "multipart/form-data",
},
}).then((res) => {
const { data } = res;
console.log(data);
const img = document.querySelector("img");
img.src = "/" + data.path;
});
}
</script>
- 1. formdata 객체에 input 테그를 통해 받은 정보를 append 한다.
- 2. axios 요청을 보낼 때 header 변수를 통하여, 해당 파일이 multipart/form-data" 타입임을 명시한다.
- 3. 서버에 요청을 보낸 뒤 다시 .then 이나 async - await 방식을 통해 정보를 받은 이후 추가 처리를 하면 된다.
(백엔드)
app.post("/dynamicFile", uploadDetail.single("dynamicUserFile"), (req, res) => {
console.log(req.file);
res.send(req.file);
});
서버 단에서 해줘야 할 역할은 앞선 3가지 방식과 크게 다르지 않다.
3. multer의 세부 설정
#. 경로 뿐 아니라 파일명, 파일 크기 등을 직접 지정, 제어할 수 있다.
const uploadDetailpar = multer({
storage: multer.diskStorage({
//destination : 경로 설정
destination(req, file, done) {
// done : callback function
// done(null, "~~~") 여기서 null은 error를 의미하는 매개 변수
// 에러가 없으므로 "null" 이라고 전달하여 콜백함수를 호출
done(null, "uploads/");
},
filename(req, file, done) {
const ext = path.extname(file.originalname); // 파일 "확장자를 추출"
console.log("ext :", ext);
console.log(path.basename(file.originalname, ext));
done(null, path.basename(file.originalname, ext) + req.body.id + ext);
},
}),
limits: { fileSize: 5 * 1024 * 1024 },
});
storge : 저장한 공간에 대한 정보
diskStorage : 파일을 디스크에 저장하기 위한 모든 제어 기능을 제공
destination : 저장할 경로
filename : dest 속성을 통해 설정한 폴터에 넣을 파일의 이름.
4. multer를 간단하게 정리해보면 ...
• single() : 하나의 파일 업로드
• req.file : 파일 하나
• req.body : 나머지 정보
• array() : 여러 파일을 업로드할 때 사용, 하나의 요청 안에 여러 개의 파일이 존재할 때
• req.files : 파일 n개
• req.body : 나머지 정보
• fields() : 여러 파일을 업로드할 때 사용, 하나의 요청이 아닌 여러 개의 요청이 들어올 때
• req.files : 파일 n개
• req.body : 나머지 정보
참고 자료
- 코딩온 부트 캠프 ppt 자료
'KDT 코딩온 개발 14기 수강일기' 카테고리의 다른 글
KDT 포스코X코딩온 웹 과정 14기 22일 - 데이터베이스 (0) | 2024.11.30 |
---|---|
KDT 포스코X코딩온 웹 과정 14기 20일 - 동적 폼 전송 (1) | 2024.11.29 |
KDT 포스코X코딩온 웹 과정 14기 19일 - Node.js (2) | 2024.11.29 |
KDT 포스코X코딩온 웹 과정 14기 18일 - callback, promise, async (2) | 2024.10.27 |
KDT 포스코X코딩온 웹 과정 14기 17일 - 구조분해할당, 클래스, 연산자 (0) | 2024.10.27 |