HTML - 파일 전송에 사용되는 multipart / form-data 란?

컴업·2021년 12월 22일
4

HTML form 태그는 우리가 인터넷에서 회원가입을 하거나, 글을 작성하는등 정보를 서버로 전송할 때 정말 많이 사용되는 아이입니다.

이 form에는 여러가지 타입이 존재합니다.

그중에서 이번시간에는 파일을 전송할 때 사용하는 multipart / form-data에 대해 알아보겠습니다.

application/x-www-form-urlencoded

application/x-www-form-urlencoded 은 폼의 가장 기본적인 타입입니다.

일반적으로 우리가 그냥 사용하는 폼이 대부분 이 타입이죠.

대충 이렇게 생겼죠?
<form action="/save" method="post">
 <input type="text" name="username"/>
 <input type="text" name="age"/>
 <button type="submit">전송</button>
</form>

위에 작성한 html 코드처럼 enctype 옵션을 지정하지 않으면 웹 브라우저는 요청 HTTP 메세지의 헤더에 Content-Type: application/x-www-form-urlencoded을 붙여 알아서 타입을 지정합니다.

이렇게 생긴 폼에서 만들어진 요청 HTTP 메시지를 간략하게 나타내면 아래와 같습니다.

POST /save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded

username=kim&age=20

폼에 입력한 항목을 HTTP body에 '&'으로 구분지어 전송합니다. (query parameter와 똑같죠?)

그냥 문자열, 숫자등을 전송할때는 이런방식이 전혀 문제가 되지 않습니다.
그러나 파일을 업로드하기 위해서는 문자가아닌 바이너리 데이터를 전송해야합니다.
바이너리 데이터는 온갖 조합이 다 나오기 때문에 &로 구분할 수 없습니다.

또한 파일을 전송할 때 파일만 '띡' 전송하는 경우는 드물고 다른 정보도 함께 전송하는 경우가 많습니다.

예를 들어 username, age, profil photo 이렇게 세가지를 함게 전송 하는 것 처럼 말이지요.

요때 사용되는 아이가 바로! multipart/form-data!!

multipart/form-data

이 방식을 사용하려면 폼 태그에 enctype="multipart/form-data"를 지정해야 합니다.

이렇게요
<form action="/save" method="post" enctype="multipart/form-data">
 <input type="text" name="username"/>
 <input type="text" name="age"/>
 <input type="file" name="file1"/>
 <button type="submit">전송</button>
</form>

multipart/form-data으로 지정된 폼에서 만들어진 HTTP 요청 메세지는 조금 다른 형태를 띄고있습니다.

POST /save HTTP/1.1
Host: localhost:8080
Content-Type: multipart/form-data; boundary=-----%%%
Content-Length: 12309

-----%%%
Content-Disposition: form-data; name="username"

steve
-----%%%
Content-Disposition: form-data; name="age"

25
-----%%%
Content-Disposition: form-data; name="file1"; filename="profile.png"
Content-Type: image/png

2q432#@$%#%#@REWFfsf3e3f3@4ewR$f4r4wF4gs4t4obvy734or84r4v#%Y^&B$%^$%&E^%$^@%C%$QRTA$f4btwRWwa3rw3r ...
-----%%%

위처럼 각 폼 항목마다 Content-Disposition 헤더가 붙고 부가정보가 붙어있습니다.
file의 경우 Content-Type이 추가되고 바이너리 데이터가 전송됩니다.

모든 항목은 "-----%%%" 처럼 임의로 생성되는 바운더리를 통해 구분되고, 이 바운더리는 UUID로 매번 임의로 생성됩니다.

바운더리로 구분된 각 항목을 Part라 합니다!



참고
Inflearn 김영한 선생님, 모든 개발자를 위한 HTTP 웹 기본 지식

profile
좋은 사람, 좋은 개발자 (되는중.. :D)

0개의 댓글