관리 메뉴

번데기 개발자의 메모장

HTTP: Content-Type 에 대해 알아보자 (application/json, application/x-www-form-urlencoded, multipart/form-data) 본문

웹 프론트엔드/웹개발 용어 및 개념 정리

HTTP: Content-Type 에 대해 알아보자 (application/json, application/x-www-form-urlencoded, multipart/form-data)

번데기 개발자 2022. 2. 16. 03:34
반응형

웹 개발을 하게 되면 HTTP에 대해 조금 알아두는 것이 좋습니다.

 

그중에서 Content-Type에 대한 이해가 부족한 것 같아 정리를 해보았습니다.

 

Content-Type

 

Content-Type은 api 연동시에 보내는 자원을 명시하기 위해 보통 사용합니다.

 

Content-Type을 깊게 이해하기 위해서는 HTTP의 request의 구조를 이해하는 것이 좋습니다. 

 

HTTP의 Request는 다음과 같이 4개의 파트로 나눌 수 있습니다.

 

 

위 그림에서 Message Body에 들어가는 타입을 HTTP Header에 명시해줄 수 있는데 이때 명시해줄 수 있도록 해주는 필드가 바로 Content Type입니다.

 

예를 들어 api 요청 시 request에 실어 보내는 데이터(body)의 type정보를 표현합니다.

 

그중에 Text타입으로는 text/css, text/javascript, text/html, text/plain 등이 있습니다. 

 

또 file을 실어보내기 위해서는 multipart/form-data가 있고 Application 타입으로는 application/json, application/x-www-urlencoded가 있습니다.

 

Content-Type의 형식으로는 위 말고도 여러 가지가 있지만 가장 많이 사용되고 헷갈리는 것 위주로 정리를 해보겠습니다.

 

 

application/json과 application/x-www-form-urlencoded

 

요즈음의 대부분의 request에 대한 Content-Type은 application/json 타입인 것이 많습니다.

 

application/json은 RestFul API를 사용하게 되며 request를 날릴 때 대부분 json을 많이 사용하게 됨에 따라 자연스럽게 사용이 많이 늘게 되었습니다.

 

application/x-www-form-urlencoded는 html의 form의 기본 Content-Type으로 요즘은 자주 사용하지 않지만 여전히 사용하는 경우가 종종 존재합니다.

 

차이점은 application/json은 {key: value}의 형태로 전송되지만 application/x-www-form-urlencoded는 key=value&key=value의 형태로 전달된다는 점입니다.

 

즉 application/x-www-form-urlencoded는 보내는 데이터를 URL인코딩 이라고 부르는 방식으로 인코딩 후에 웹서버로 보내는 방식을 의미합니다. (따라서 사용하는 library나 framework에서 x-www-form-urlencoded를 사용할 경우 body 인코딩이 지원하는지 꼭 확인해봐야 합니다.)

 

예제 코드 (application/json)

let data = {
    id: id,
    pw: pw
}
axios.post(url,  JSON.stringify(data), { // json을 json타입의 text로 변환
  headers: {
    "Content-Type": `application/json`, // application/json 타입 선언
  },
})
.then((res) => {
  console.log(res);
});

 

예제 코드 (application/x-www-form-urlencoded)

import qs from 'qs';
const data = { 'bar': 123 };
axios.post(
  '/foo', 
  qs.stringify(data), // json을 queryString 타입의 text로 변환
  headers: {
    "Content-Type": `application/x-www-form-urlencoded`, // x-www-form-urlencoded 타입 선언
  },
})
.then((res) => {
  console.log(res);
});

 

mutipart/form-data

 

파일 업로드를 구현할 때 클라이언트가 web 브라우저라면 폼을 통해서 파일을 전송합니다.

 

웹 브라우저가 보내는 HTTP 메시지는 Content-Type 속성이 multipart/form-data로 지정되고 정해진 형식에 따라 메시지를 인코딩하여 전송합니다. 

 

참고로 multipart는 MIME(Multipurpose Internet Mail Extensions) 타입 중의 하나입니다.

 

본론으로 돌아와서 multipart/form-data를 처리하기 위한 서버는 멀티파트 메시지에 대해서 각 파트별로 분리하여 개별 파일의 정보를 얻게 됩니다.

 

여기서 중요한 점은 이미지 파일을 전송한다고 해서 png나 jpg 파일을 전송하는 것이 아니라는 것입니다.

 

이미지 파일도 문자로 이루어져 있기 때문에 이미지 파일을 문자로 생성하여 HTTP request body에 담아 서버로 전송하는 것입니다.

 

multipart가 생긴 배경

 

기본적으로 form이 submit 되면 HTTP 헤더에 지정한 타입의 데이터가 Body에 담겨서 서버로 보내지게 됩니다.

 

정리하면 다음과 같습니다.

 

  • HTTP Request의 Body에 클라이언트가 전송하려는 데이터가 담김
  • Body에 들어가는 데이터의 타입을 HTTP Header에 명시해 줌으로써 서버가 타입에 따라 알맞게 처리
  • 해당 Body의 타입을 명시하는 Header가 Content-Type

 

이때 중요한 점은 HTTP Request의 Body가 한 종류의 타입이 대부분이라는 점입니다.

 

Content-Type도 한 종류만 명시할 수 있는데 예를 들어 text이면 text/plain, xml이면 text/xml, png이미지이면 image/png 이런 식으로 명시하여 데이터를 서버로 전송하게 됩니다.

 

하지만 파일 업로드의 상황을 살펴보면 사진을 업로드하는 경우 사진에 대한 설명을 위한 input과 사인 파일을 위한 input 2개가 들어갑니다.

 

위 두 input에 대한 Content-Type은 전혀 다른데, 이미지의 설명에 대한 Content-Type은 application/x-www-form-urlencoded일 것이고, 사진 파일에 대한 Content-Type은 image/png 일 것입니다.

 

두 종류에 대한 Content-Type이 하나의 HTTP Request Body에 들어가야 하는데 이때 2종류의 데이터를 구분해서 넣어주는 방법이 필요해서 multipart라는 개념이 들어가게 되었습니다.

 

 

예제 코드

var photoFile = document.getElementById("photo");
const formData = new FormData();
formData.append("photo", photoFile.files[0]); // 파일 첨부
formData.append("comment", commentValue); // 텍스트 첨부
axios.post('https://domain/form-post-url', formData, { // 요청
  headers: {
    'Content-Type': 'multipart/form-data'
  }
})

 

 

이상으로 Content-Type에 대해서 알아보았는데요, 평소에 별 관심을 가지지 않았던 Content-Type에 대해서 조금 관심을 갖고 살펴보니 흥미로운 내용들이 많은 것 같습니다.

 

HTTP와 조금 더 친숙해진 것 같고, 추후에도 HTTP에 대해서 궁금증이 생기는 부분이 생길 때마다 정리해서 메모해 놓도록 하겠습니다.

 

감사합니다.!

 

 

참고

 

Http Method는 POST, Content-Type이 application/x-www-form-urlencoded인 경우 body를 encoding하는게 맞을까?

 

Http Method는 POST, Content-Type이 application/x-www-form-urlencoded인 경우 body를 encoding하는게 맞을까?

Http Method는 POST, Content-Type이 application/x-www-form-urlencoded인 경우 body를 encoding하는게 맞을까? - postbodyEnc.md

gist.github.com

 

HTTP multipart/form-data 란?

 

HTTP multipart/form-data 란?

프로젝트를 진행하면서 프론트 -> 백엔드로 이미지를 전송하는 경우가 있었다.오늘은 HTTP, multipart, multipart/form-data 세 가지 키워드에 대해 알아보고, 그 중에서 중요한 개념중에 하나인 multipart/for

velog.io

 

반응형
4 Comments
댓글쓰기 폼