Programming/Web

x-www-form-urlencoded 타입이란 (multipart/form-data와의 차이점)

Jan92 2023. 8. 23. 22:18

x-www-form-urlencoded와 multipart/form-data 차이점

 

//기존에 설정된 springdoc consumes
default-consumes-media-type: multipart/form-data

//변경된 설정
default-consumes-media-type: application/x-www-form-urlencoded

프로젝트 작업 중 동료분으로부터 'multipart/form-data'로 설정된 springdoc default-consumes-media-type을 'application/x-www-form-urlencoded'로 바꾸는 게 어떻겠냐는 제안을 받았습니다.

 

(consumes: 클라이언트가 서버에 보내는 데이터 타입, produces: 서버가 클라이언트에게 반환하는 데이터 타입)

 

이때까지 작업을 하면서 대부분 값을 받을 때 content-type으로 application/json 사용하거나,  form을 사용하는 경우 multipart/form-data를 default로 설정하고 사용했었기 때문에 application/x-www-urlencoded라는 content-type은 사실 좀 생소했는데요.

 

해당 포스팅은 'application/x-www-urlencoded content-type은 무엇인지', 그리고 'multipart/form-data와는 어떻게 다른지' 정리한 내용입니다.

 


application/x-www-urlencoded

 

'application/x-www-urlencoded'html form을 통한 POST 전송 방식 중 가장 기본이 되는 content-type인데요.

urlencoded라는 단어로부터 알 수 있는 것처럼 보내는 데이터를 url 인코딩 후 웹 서버에 보내는 방식입니다.

 

모든 브라우저에서는 application/x-www-form-urlencoded content-type에 대해 body의 데이터를 자동으로 encoding 하도록 구현되어 있는데요.

브라우저가 아닌 애플리케이션 로직에서 해당 타입으로 POST 요청을 보낼 때는 framework 또는 library를 통해 body에 대한 인코딩이 되는지 여부를 확인해주어야 합니다.

 

또한 인코딩이 필요하기 때문에 크기가 큰 데이터에 대해 해당하는 방식으로 보내기가 적합하지 않다는 특징이 있습니다.

 

 

* x-www-form-urlencoded에 대한 인코딩 규칙은 아래와 같습니다.

 

1. key=value 형식

요청 데이터를 키(key)와 값(value)의 쌍으로 구성합니다. 각 쌍은 '='로 키와 값이 연결되며, 여러 개의 key-value 쌍은 '&'로 구분되는데요. 이러한 형식을 통해 여러 개의 데이터를 한 번에 전송할 수 있습니다.

 

2. URL Encoding

데이터의 특수 문자나 공백과 같은 부분이 url 인코딩 규칙[RFC1738]에 따라 인코딩 됩니다. 특정 문자들은 '%' 기호와 그 문자의 ASCII 코드를 표시하여 인코딩 됩니다.

(공백은 '+' 기호로 인코딩 됩니다.)

 

 

***

content-type은 api 연동 시에 보내는 자원을 명시하기 위해 사용되는데요.

Message Body에 들어가는 타입을 Http Header에 명시해 줄 수 있는데, 이때 데이터 타입을 명시해 줄 수 있는 필드가 바로 content-type입니다.

 

 


multipart/form-data

 

위에서 이야기한 것처럼 application/x-www-form-urlencoded 방식은 인코딩 과정이 들어가기 때문에 대량의 데이터를 보내는 것에는 적합하지 않은데요.

때문에 파일이나 이미지 같은 바이너리 데이터가 포함된 데이터를 보낼 때는 'multipart/form-data'라는 content-type을 사용하게 됩니다.

 

multipart/form-data의 특징은 웹 클라이언트가 요청을 보낼 때 폼 데이터를 여러 부분으로 나눠서 보낼 수 있다는 것인데요.

(각 부분은 각각의 Content-Disposition 헤더와 내용으로 구성되어 있습니다.)

 

예를 들어 이미지 파일과 해당 이미지 파일에 대한 설명을 폼 데이터로 서버에 요청 보낸다고 했을 때, 이미지 파일에 대한 content-type은 image/jpeg 또는 image/png 등이 될 것이고, 설명에 대한 content-type은 application/x-www-form-urlencoded가 될 것입니다.

 

즉, 이렇게 서로 다른 두 개의 content-type을 가진 데이터를 하나의 HTTP Request Body에 보내야 하는데요.

때문에 폼 데이터를 여러 부분으로 나눠서 보낼 수 있는 multipart/form-data가 등장하게 된 것입니다.

(데이터가 여러 부분으로 나눠지는 것에 대해서는 바로 아래 전송 방식 비교 부분에서 예시를 살펴보실 수 있습니다.)

 

 


위 두 가지 전송 방식에 대한 비교 (+ application/json)

 

application/x-www-form-urlencoded 예시

 

 

multipart/form-data 예시

(input1과 input2가 각각의 영역에 나눠서 보내지는 것을 볼 수 있습니다.)

 

 

application/json 예시

위 이미지는 input: value1, input2: value2라는 key-value 값을 각각의 타입으로 요청했을 때의 Request Body인데요.

 

결론적으로 단순한 텍스트 데이터를 전송할 때는 'multipart/form-data'에 비해 'application/x-www-form-urlencoded'를 선택하는 것이 이론상 데이터 효율성 측면에서 더 좋습니다.

(예시와 같이 동일한 데이터를 보냈을 때의 content-length만 비교해 봐도 알 수 있습니다.)

 

 

 

< 참고 자료 >

https://dev.to/getd/x-www-form-urlencoded-or-form-data-explained-in-2-mins-5hk6

https://gist.github.com/jays1204/703297eb0da1facdc454