[포스코x코딩온 웹 풀스택 10기] 6주차 회고_파일 업로드 (body-parser, multer)

onee·2023년 12월 5일
0
post-thumbnail
post-custom-banner

📖 수업내용


# body-parser

: 데이터를 쉽게 처리할 수 있도록 도와주는 미들웨어이다.

  • 요청의 body를 req.body로 받아서 사용할 수 있도록 해준다.
  • 하지만, 멀티파트 데이터(예: 이미지, 동영상, 파일 등)를 처리하지 못한다는 단점이 있다.
    (-> multer 이용)

express 4.16.0 버전 이상부터 내장모듈로 포함되어 있기 때문에 별도로 설치하지 않아도 된다.

app.use(express.urlencoded({ extended: true }));
app.user(express.json());

express.urlencoded({ extended: true })

🤷🏻‍♀️ urlencode 린?

  • HTTP 통신할 때 데이터 인코딩하는 방식 중 하나이며, 인코딩하는 방식은 request 할 때 사용하는 enctype에 따라 결정된다.

    ①  application/x-www-form-urlencoded : 'URL encoded form', default 값이다.
      -> key1=value&key2=value 방식으로 변환되어 요청된다.

  ②  multipart/form-data : 'Multipart/form-data', 주로 파일 업로드 할 때 사용된다.

  ③  text/plain : 인코딩 없는 단순 문자열이다.

  • { extended: true } :
    • default 값
    • 'query string(qs)' 라이브러리로 URL-encoded 데이터를 파싱한다는 의미이다.

express.json()

  • json 형태의 request가 전해졌을 떄, body를 파싱하는 미들웨어이다.

참고1참고2



# multer

: 클라이언트에서 서버로 파일을 전송하는 방법이다.

<input type="file" name="userfile" >
// name 속성은 서버에서 파일을 인식할 이름이 된다.(서버와 동일하게 설정)

❗️multerenctype="multipart/form-data"가 아닌 폼에서는 동작하지 않기 떄문에 반드시 설정해주어야 한다.

# multer 설정하기

-> dest: 파일을 업로드하고 그 파일이 저장될 경로를 지정하는 속성이다.


-> stroage: 저장할 공간에 대한 정보

  • diskStorage: 파일을 디스크에 저장하기 위한 모든 제어 기능을 제공
  • destination: 저장할 경로
  • filename: 파일명

-> limits : 파일 제한

  • fileSize: 파일 사이즈 제한

1) 일반 폼 전송

  • form 태그 안에 button type="submit"을 사용한다.

  • form이 제출되면 다른 페이지로 이동된다.

  • 작성 예시 :

<form action="/upload" method="POST" enctype="multipart/form-data">
  <input type="file" name="userfile" />
  <button type="submit">업로드</button>
</form>

하나의 파일을 업로드
: single()

<!-- html -->
	<h2>Single file upload</h2>
    <p>하나의 인풋에 하나의 파일을 업로드</p>
    <form action="/upload" method="post" enctype="multipart/form-data">
      <input type="file" name="userfile" />
      <input type="text" name="title" /><br /><br />
      <button>업로드</button>
    </form>

여러 개의 파일을 업로드
: array() -> 하나의 요청 안에 여러 개의 파일이 존재할 때 사용한다.
: fields() -> 하나의 요청이 아닌 여러 개의 요청으로 들어올 때 사용한다.

<!-- html -->
	<h2>Multi file upload v1</h2>
    <p>하나의 인풋에 여러 개의 파일을 업로드</p>

    <!-- 하나의 인풋에 여러 개 업로드 할 경우 multiple 속성 추가 -->
    <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>

    <hr />

    <h2>Multi file upload v2</h2>
    <p>여러 개의 인풋에 각각의 파일을 업로드</p>

    <!-- 하나의 인풋에 여러 개 업로드 할 경우 multiple 속성 추가 -->
    <form action="/upload/fields" method="post" enctype="multipart/form-data">
      <input type="file" name="userfile1" />
      <input type="text" name="title" /><br /><br />
      <input type="file" name="userfile2" />
      <input type="text" name="title" /><br /><br />
      <button>업로드</button>
    </form>


2) 동적 폼 전송

  • button type="button"을 사용한다.
  • form 태그에 method, action이 아닌 name을 작성한다.
  • form이 제출되었을 때, 현재 경로에서 요청에 대한 결과는 받는다.
<!-- html -->
	<h2>동적 파일 업로드</h2>
    <input type="text" id="title" placeholder="TITLE" />
    <input type="file" name="dynamicFile" id="dynamicFile" /><br /><br />
    <button type="button" onclick="fileUpload()">업로드</button>
// js
 	function fileUpload() {
        // js 만으로 폼 전송
        // file을 같이 전송 -> FormData 객체를 활용하기!
        // FormData란?
        // form 태그의 데이터를 동적으로 제어할 수 있는 기능, 보통 axios, ajax 등등과 함께 사용

        const formData = new FormData();
        const file = document.querySelector("#dynamicFile");
        const title = document.querySelector("#title");

        console.log(file); // 선택한 파일 요소
        console.log(file.files); // 업로드한 파일 객체
        console.log(file.files[0]); // 업로드한 첫 파일

        // append(key, value)
        formData.append("dynamicFile", file.files[0]);
        formData.append("title", title.value);

        axios({
          method: "post",
          url: "/dynamic",
          data: formData,
          headers: {
            "Content-Type": "multipart/form-data",
            // enctype 지정과 동일
          },
        }).then((res) => {
          console.log(res.data);
          //   구조분해할당
          const { file, title } = res.data;

          console.log("file > ", file);
          // 이미지가 저장된 경로인 file.path 이용
          const imgElem = document.querySelector("img");
          imgElem.src = "/" + file.path;
          imgElem.alt = title;
          imgElem.classList.add("profile");
        });
      }



참고: 포스코x코딩온 강의 자료(1012파일업로드.pdf)



👩🏻‍💻 학습


# express.urlencoded({ extended: true })

< 사용 가능한 설정 >
extended(default : true) : "query string"(일명 qs) 라이브러리로 URL-encoded 데이터를 파싱할지(true) 안 할지에 대한 설정이다.
inflate(default : true): 압축된 body 데이터를 허용할 지(true) 안 할지(false)를 설정한다.
limit(default : 100kb) : body로 전달되는 데이터의 크기를 제한한다.
parameterLimit(default : 1000) : URL-encoded 데이터의 파라미터 갯수를 몇 개까지 제한 할지에 대한 설정이다.
type(default = application/x-www-form-urlencoded) : 어떤 타입을 이 미들웨어에서 파싱이 될지 정하는 설정. 함수가 들어올 수도 있는데, fn(req)의 형식으로 호출한다. 반환값이 truly 하면 파싱된다.
verify(default = undefined) : 함수가 전달되어야 한다. 사용한다면 verify(req, res, buf, encoding) 형식으로 호출된다. buf는 Buffer를 의미하고, encoding은 request의 변환 버전을 의미한다. 함수 내에서 에러를 발생시키면 파싱을 하지 않게 만든다.


# express.json()

< 사용 가능한 설정 >
inflate(default = true) : 압축형 body를 이용 가능하게 할 것인가(true), 아닌가(false)를 설정한다.
limit(default = 100kb) : body의 데이터 크기를 제한한다.
strict(default = true) : 배열과 객체로 들어오는 값들만 처리할 것인지(true) 아닌지(false)를 설정한다.
type(default = application/json) : 어떤 타입을 이 미들웨어에서 파싱이 될지 정하는 설정. 함수가 들어올 수도 있는데, fn(req)의 형식으로 호출한다. 반환값이 truly 하면 파싱된다.
verify(default = undefined) : 함수가 전달되어야 한다. 사용한다면 verify(req, res, buf, encoding) 형식으로 호출된다. buf는 Buffer를 의미하고, encodingrequest의 변환 버전을 의미한다. 함수 내에서 에러를 발생시키면 파싱을 하지 않게 만든다.



참고




profile
Hello World 💻
post-custom-banner

0개의 댓글