티스토리 뷰

728x90
Content-Type이 무엇이며 그중 application/x-www-form-urlencoded 이 담당하는 역할이 무엇인지 알아보자. 그리고 실무에서 발생한 문제와 해결과정을 살펴보자

1. Content-Type 이란?

Content-Type에 들어가기 전, 네트워크 이야기를 잠깐 하겠다. 네트워크는 서로다른 두 매체(클라이언트 or 서버)가 데이터(리소스)를 주고 받는 단위다. 여기서 주고 받기 위해서는 프로토콜(규칙)을 서로 지키게 된다. Content-Type은 리소스의 타입을 나타내기 위해 사용된다. 

https://www.iana.org/assignments/media-types/media-types.xhtml

https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Content-Type

 

2. application/x-www-form-urlencoded

이 타입은 form data를 제출할 때, 사용이 된다. form을 제출하는 방식에는 2가지 방법(POST | GET)이 있는데 TCP SCHOOL에서 체험해볼 수 있다. 파라미터로 어떻게 데이터가 받아지는 지만 확인해보면 좋겠다.

https://www.tcpschool.com/html-tag-attrs/form-method

'&'으로 보낼 key를 분리하고 '='을 통해 value를 넣어주고 있습니다.
US-ASCII 에 의해 정의되지 않은 범위의 문자는 percent encode(%를 사용한 인코딩)된 2개의 16진수로 변환해 사용하고 있다.
https://ko.wikipedia.org/wiki/ASCII

 

그러면 클라이언트와 서버간에 있어서 지켜야 될 규칙이 있을 것이다. 바로 Character Set 이다. 이 과정을 위해서 Encoding, Decoding이 사용된다.

비유하자면 클라이언트가 한국어를 사용하고 있고 서버가 일본어를 쓴다고 하겠다. 한국어로 보내면 서버에서 바로 이해할 수 있는가? 그렇기 때문에 두 관계에 있어서 Character Set을 맞춰줘야한다.

 

3. Encoding, Decoding

우리는 UTF-8, UTF-16, CP949(MS949), EUC-KR 등 들어본 적이 있을 것이다.

컴퓨터는 0, 1의 비트를 사용하고 있다. 그래서 컴퓨터에서 영어나 한글을 이해하기 위해서는 비트를 인코딩해서 Character Set로 바꿔주어야 한다.

 

영어는 7bit로 단어, 숫자 특수기호를 표현할 수 있었다. 대표적으로 1byte(8bit)를 사용한 ASCII 코드가 여기에 해당한다.

그러나 한국어는 ASCII 만으로는 표현을 할 수 없다. 그렇기 때문에 2byte(16bit)를 사용해 EUC-KR 셋을 사용하고 있다. 이처럼 한국어 뿐만이 아닌 중국, 일본등 다양한 국가에서의 단어도 ASCII로 담을 수 없어 여러가지 Character Set이 생겨났다.

 

그러던 중 UniCode가 등장했다. 전 세계의 문자를 다루도록 처리된 표준이 생겨난거다. 덕분에 각 언어간의 문자체계의 충돌 문제를 해결 할 수 있었다. 대표적으로 우리가 잘 알고있는 UTF 계열이 여기에 해당되는데 대부분 UTF-8을 사용하고 있다.

 

4. 실무에서 발생하게 된 문제를 해결하는 과정

4.1  문제 발견

우리 서비스에서는 UTF-8 기반으로 하고 있었지만 토스페이먼츠 에스크로를 담당하는 서버에서는 EUC-KR으로 설정되어 있었다. 그러다 보니 단순하게 form 데이터 형식으로만 보냈을 때, 영어, 숫자, 기호를 제외한 한글이 깨지게 되어 의도한 명령을 수행하지 못했다.

한글로 보냈지만 토스페이먼츠 상에서 깨짐을 확인

그렇다면 어떻게 해서 이렇게 깨짐을 확인할 수 있었는 지 증명해보겠다.

 

4.2 문제 증명

"정보없음" 문자열을 토스페이먼츠에 그대로 사용하면 "??蹂댁????" 이라는 결과가 나온다.
https://dencode.com/ 에서 문자 변환을 확인해보도록 하자

UTF-8 클라이언트에서 EUC-KR 서버로 보낼 때, 데이터 형태

정보 없음을 토스로 보내는 과정에서 한글은 16진수의 hex 코드로 변환됩니다. 이를 tosspayments 에서 수신을 했을 때 데이터가 깨지게 된다. 그림을 통해 Charset을 맞춰야 한다는 걸 알 수 있다.

 

4.3 문제 해결

일단은 Charset을 변환해야 이 문제를 해결할 수 있다는 걸 파악할 수 있다.
여기서는 글이 길어지므로 별도의 게시글로 처리하겠다.

https://djunnni.tistory.com/31

 

5. 정리

외부 서비스와 연결하는 과정에서 어떤 media type과 인코딩은 무엇으로 되어있는 지 확인하는 습관을 들여야 한다.

그리고 외부 라이브러리(ex, axios)를 통해 한번에 깔끔하게 지원되지 못할 수 있으므로 자신이 사용하는 라이브러리에 대해서도 들여다 볼 필요가 있다.

 

 

 

반응형

'CS > Server' 카테고리의 다른 글

package.json에 있는 command 왜 '--'를 넣을까?  (0) 2023.10.08
Jest에서 Axios을 mocking 해보자  (0) 2023.10.08