포스코x코딩온 웹 풀스택 양성과정

[포스코x코딩온] 웹 풀스택 과정 5주차 회고 | 파일 업로드(multer)

Codult 2024. 3. 29. 21:26
728x90

 

이번 시간에는 업로드한 파일을 받아오는 과정을 배웠다.
기존에 배웠던 body-parser는 요청의 body를 받을 수 있게 도와주지만, 멀티파트 데이터(이미지, 동영상, 파일 등)는 처리하지 못한다.
멀티파트 데이터를 처리하기 위해서는 multer를 이용해야 한다.

📌 파일 업로드

  • input type="file" 을 이용하면, 사용자가 파일을 선택할 수 있는 요소가 생성된다.
  • multiple 속성을 추가하면, 여러개의 파일을 한번에 받을 수 있다.
<input type="file" name="userfile">
<input type="file" name="userfile" multiple>
  • 파일 업로드는 POST 방식으로 정보를 전송해야 한다.
  • 폼 태그의 enctype 속성은 'multipart/form-data'로 설정해야 한다.
    (multer는 multipart (multipart/form-data) 이외의 폼에서는 동작X)

 

📌 multer 미들웨어

🚩 multer 설치 & 설정

→ 설치: npm i multer
→ 설정: express와 마찬가지로, multer 불러오기

const multer = require("multer")
const path = require("path")
// path는 multer 세부설정 시, 경로에 접근할 수 있도록 하기 위해 불러와야 함.

🚩 파일 업로드 경로 설정

  • dest: 파일이 저장될 경로를 지정하는 속성으로, 자동으로 해당 이름의 폴더가 생성된다.
const upload = multer({
	dest: 'uploads/'
})
  • 세부 설정으로 경로를 포함하여 파일명, 파일 크기 등을 직접 지정할 수 있다.
    • storage: 저장할 공간에 대한 정보로, 저장 경로(destination), 파일명(filename) 등을 설정할 수 있다. 이때 설정한 저장 경로는 자동으로 폴더가 생성되지 않으므로, 직접 생성해야 한다.
    • limits: 파일 사이즈(fileSize)를 제한할 수 있다.
const uploadDetail = multer({
	storage: multer.diskStorage({ // diskStorage: 파일을 디스크에 저장하기 위한 모든 제어 기능을 제공한다.
		destination(req, file, done){
          done(null, 'uploads/'); // uploads라는 폴더에 저장한다.
        },
        filename(req, file, done) {
          const ext = path.extname(file.originalname); // 파일의 originalname에서 확장자를 빼온다.
          done(null, path.basename(file.originalname, ext) + Date.now() + ext); // 파일의 originalname에서 확장자를 제외한 부분 + 현재시간 + ext 으로 filename 설정한다.
		}
	}),
	limits: {fileSize: 1024 * 1024 * 5}
})

📌 파일 업로드

🚩 하나의 파일 업로드

  • .single("파일 업로드 요소의 name") 으로 해당 파일을 업로드한다.
  • req.file 으로 업로드된 파일의 정보를 확인할 수 있다.
  • req.body 으로 나머지 전체 데이터 확인할 수 있다.

🚩 여러 개의 파일 업로드 (하나의 요청 안에 여러 개의 파일이 있을 때 (multiple))

  • array('파일 업로드 요소의 name')으로 해당 파일들을 업로드 한다.
  • req.files 으로 파일들의 정보 확인할 수 있다.

🚩 여러 개의 파일 업로드 (여러 개의 요청이 들어올 때)

  • fields([{name: '파일 업로드 요소의 name1'}, {name: '파일 업로드 요소의 name2'}]) 형태로 해당 파일들을 업로드 한다.
  • req.files으로 파일들의 정보 확인할 수 있다.

📌 동적 파일 업로드

axios와 같은 비동기식 http 통신을 통해, 동적 파일 업로드를 할 수 있다.

🚩 axios 이용

  • form 태그에 적었던 내용을 axios 방식으로 적어주면 된다.
  • 요청을 보내는 부분에, headers를 추가하여 "Content-Type": "multipart/form-data"로 설정해준다.
  • 이미지를 페이지에 띄우고 싶다면, 서버에서 응답받은 데이터에서 img src 주소를 뽑아 속성 값으로 추가하면 된다.

🚩 추가) 폼 형식이 아닌 요소의 파일을 업로드 하는 방법

FormData 객체를 이용하여, 폼 형식으로 만들어 백엔드로 보내주면 된다. (FormData 객체는 form태그의 데이터를 동적으로 제어할 수 있는 기능을 제공함)

<input type="file" name="dynamic-userfile" id="dynamic-file">
<input type="text" name="text">
<button type="button" onclick="fileupload()"> 업로드 </button>

<script>
  function fileupload() {
  const file = document.getElementById("dynamic-file");
  console.log(file.files[0]); // .files으로 file 요소에 있는 파일 정보를 불러올 수 있음
  
  const formData = new FormData(); 	// FormData 객체 가져옴
  formData.append("dynamic-userfile", file.files[0]);
  formData.append("text", text.value);
  
  axios({
    method: "POST",
    url: "/dynamicFile",
    data: formData,
    headers: {
      "Content-Type": "multipart/form-data",
    }
  }).then((res) => {
    console.log("res",res);
  })
}
</script>


내가 오늘 실습하면서 막혔던 이유

body-parser 설정 안한 상태에서 req.body 불러와서 계속 undefined 뜨고 있었음 (body 불러올 때는 body-parser나 multer 확인!!) & 여러 요청이 들어와 파일 업로드 할 때, 파일마다 하나씩 객체 중괄호{}로 추가해주어야 함.

 
728x90