2026년 11월 13일 금요일

Windows 에서 curl -d 로 한글 JSON 을 보내면 깨지는 문제

Windows 의 Git Bash 에서 한글이 들어간 JSON 을 curl -d '...' 로 보냈더니 서버에는 깨진 글자가 저장됐다. 명령도 응답도 정상이라 한참 뒤에야 알았다.

증상

curl -X POST https://api.example.com/items \
  -H 'Content-Type: application/json' \
  -d '{"title":"테스트 항목"}'

응답은 200 이고 오류도 없다. 그런데 저장된 제목을 다시 조회하면 한글이 물음표나 엉뚱한 글자로 바뀌어 있다. 영문만 보낼 때는 전혀 문제가 없어서 스크립트를 한참 쓰다가 발견했다.

원인

명령줄 인자는 프로세스로 넘어가는 과정에서 Windows 의 코드 페이지 변환을 거친다. 셸 화면에는 UTF-8 로 보여도, 실제로 curl.exe 가 받는 바이트는 시스템 ANSI 코드 페이지(한국어 Windows 라면 CP949)를 거치면서 달라질 수 있다. 헤더에는 UTF-8 JSON 이라고 적어 보내면서 본문은 다른 인코딩이 되니, 서버는 그것을 UTF-8 로 해석하다가 깨뜨린다.

어떤 셸에서, 어떤 curl 을, 어떤 터미널 설정으로 실행했는지에 따라 될 때도 있고 안 될 때도 있다는 점이 더 나쁘다.

해결

본문을 명령줄에 적지 않는다. UTF-8 파일로 저장하고 파일에서 읽게 한다.

# body.json 을 UTF-8 로 저장한 뒤
curl -X POST https://api.example.com/items \
  -H 'Content-Type: application/json; charset=utf-8' \
  --data-binary @body.json
  • -d @file 이 아니라 --data-binary @file 을 쓴다. -d 는 파일의 줄바꿈을 제거한다.
  • 파일은 BOM 없는 UTF-8 로 저장한다. Windows PowerShell 5.1 의 Set-Content 는 기본이 ANSI 라서 -Encoding utf8 을 줘야 하고, 그 경우 BOM 이 붙을 수 있으니 편집기나 스크립트 언어로 쓰는 편이 안전하다.

정리

한글·일본어·이모지처럼 멀티바이트 문자가 들어가는 요청 본문은 Windows 에서 명령줄 인자로 넘기지 않는다. 파일로 저장해서 --data-binary @파일 로 보내면 셸과 터미널 설정에 상관없이 같은 바이트가 나간다.

댓글 없음:

댓글 쓰기

반도체 주식을 보기 전에 그려 두는 지도 — 설계, 파운드리, 메모리, 장비, 소재, 후공정

"반도체주"라고 한 묶음으로 부르지만, 그 안의 회사들은 하는 일도 돈 버는 방식도 전혀 다르다. 같은 뉴스에 어떤 회사는 오르고 어떤 회사는 내리는 이유가 여기에 있다. 종목을 들여다보기 전에 머릿속에 그려 두면 좋은 지도를 정리한...