HTTP로 서버에 이미지 전송하기(multipart/form-data)

이동근·2022년 10월 25일
0

회사에서 클라이언트측에서 서버 측으로 이미지를 전송하여 S3스토리지에 저장하는 기능을 구현하게 되었다.

과거에 같은 기능을 사이드 프로젝트에서 구현해본 적 있지만(HTTP multipart/form-data 타입을 이용), 깊게 이해하지 않고 구현했기에 시간을 내서 정리해보려고 한다.

우선, HTTP헤더의 필드 중 하나인 Content Type에 대해서 알아보자

Content-Type

Content-Type 개체 헤더는 리소스의 media type을 나타내기 위해 사용됩니다.
- 위키백과

어떤 유형의 미디어 타입이 전송되고 있는지 알려주는 것이 주요 목적이다.

HTTP 프로토콜에서도 송수신하는 자원의 형식을 명시하기 위해 헤더에 이 데이터를 실어서 보낸다.

Content-Type은 세부적으로 media-type / charset / boundary로 나눌 수 있다.

Media Type / MIME Type

미디어 타입(media type), MIME 타입(MIME type), 콘텐츠 타입(content type)은 인터넷에 전달되는 파일 포맷과 포맷 콘텐츠를 위한 2 부분의 식별자이다.
- 위키백과

=> 송수신하는 데이터가 어떤 포맷인지 식별 할 수 있게 함.

일반적으로 type/subtype 구조로 사용됨.

예를 들어 다음과 같은 타입들을 볼 수 있음.

text/plain
text/html
image/jpeg
image/png
audio/mpeg
audio/ogg
audio/*
video/mp4
application/octet-stream
...

자세한 내용은 MIME 타입에 대한 MDN 문서를 참고해보자
(https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/MIME_Types)

Multipart/form-data

만약에 보내려는 메시지에 담겨진 데이터가 하나의 포맷으로 구성되어 있지 않고 여러 포맷의 데이터를 전달하려면 어떻게 해야할까?

각각의 다른 Content-Type을 가진 메시지를 여러번 쏴야 할까?

이런 상황에서 multipart/form-data타입을 사용 할 수 있다.

multipart/form-data또한 MIME Type중 하나이며, 일반적으로 브라우저에서 서버로 HTML Form의 데이터를 전송 할 때 사용 할 수 있다.

복합적인 포맷의 데이터를 전송하는 문서 형식으로써, 경계(이중 대시 '--' 로 시작되는 문자열)로 구분되어지는 다른 파트들로 구성된다.

각 파트는 그 자체로 개체이며 자신만의 HTTP 헤더를 가지는데, 파일 업로드 필드를 위한 헤더로는 Content-Disposition, 그리고 가장 일반적인 것 중 하나인 Content-Type이 있다.(Content-Length은 경계선이 구분자로 사용되므로 무시)

예시)

Content-Type: multipart/form-data; boundary=aBoundaryString
(other headers associated with the multipart document as a whole)

--aBoundaryString
Content-Disposition: form-data; name="myFile"; filename="img.jpg"
Content-Type: image/jpeg

(data)
--aBoundaryString
Content-Disposition: form-data; name="myField"

(data)
--aBoundaryString
(more subparts)
--aBoundaryString--
...

예제

<form action="/" method="post" enctype="multipart/form-data">
  <input type="text" name="description" value="some text">
  <input type="file" name="myFile">
  <button type="submit">Submit</button>
</form>

예를 들어 위와 같은 HTML Form으로 생성하는 메시지는 다음과 같다.

POST / HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=---------------------------8721656041911415653955004498
Content-Length: 465

-----------------------------8721656041911415653955004498
Content-Disposition: form-data; name="myTextField"

Test
-----------------------------8721656041911415653955004498
Content-Disposition: form-data; name="myCheckBox"

on
-----------------------------8721656041911415653955004498
Content-Disposition: form-data; name="myFile"; filename="test.txt"
Content-Type: text/plain

Simple file.
-----------------------------8721656041911415653955004498--
...

2022년 10월 25일 우선 글 등록하고 지속적으로 수정할 예정

참고자료


https://velog.io/@kyeongsoo5196/FormData%EB%A1%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%ED%8C%8C%EC%9D%BC-%EC%A0%84%EC%86%A1
https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Content-Type
https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/MIME_Types
https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
https://ko.wikipedia.org/wiki/%EB%AF%B8%EB%94%94%EC%96%B4_%ED%83%80%EC%9E%85
https://ko.wikipedia.org/wiki/MIME
https://stackoverflow.com/questions/26723467/postman-chrome-what-is-the-difference-between-form-data-x-www-form-urlencoded

profile
PompitzGeneral

1개의 댓글

comment-user-thumbnail
2022년 11월 14일

멋져요

답글 달기
Powered by GraphCDN, the GraphQL CDN