[TIL] body에 문자열을 보낼 때

minami·2025년 6월 14일

일개미

목록 보기
8/13
post-thumbnail

fetch 요청 시 body에 문자열을 보낼 때 주의할 점

오늘은 fetch로 POST나 PATCH 요청을 보낼 때, body에 문자열을 어떻게 다뤄야 하는지 정리해본다.


상황 1. 객체일 때

가장 기본적인 케이스.

const data = { name: 'Alice' }

fetch('/api/user', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(data), // ✅ 꼭 stringify 해줘야 함
})

상황 2. 이미 JSON 문자열인 경우

이미 JSON.stringify() 된 문자열이라면, 다시 stringify할 필요는 없다.

const jsonString = JSON.stringify({ name: 'Alice' })

fetch('/api/user', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: jsonString, // ✅ 그대로 사용
})

❌ 이중 stringify는 절대 금지!

body: JSON.stringify(jsonString) // ❌ "\"{\\\"name\\\":\\\"Alice\\\"}\"" 이런 괴상한 문자열이 전송됨

상황 3. 단순 문자열인 경우 (e.g. "hello", "id123")

단순 문자열을 보낼 때도 JSON.stringify()는 필요 없다.

const message = "hello world"

fetch('/api/message', {
  method: 'POST',
  headers: {
    'Content-Type': 'text/plain', // 📌 JSON이 아님을 명확히!
  },
  body: message, // ✅ 그대로 전송
})

❌ 여기서도 stringify를 하면 안 됨:

body: JSON.stringify(message) // ❌ "\"hello world\"" 전송됨

유틸: JSON 문자열인지 검사하는 함수

function isValidJSON(str: string) {
  try {
    JSON.parse(str)
    return true
  } catch {
    return false
  }
}

결론

  • body에 들어가는 건 항상 string이어야 하지만,
    그게 JSON string이냐, 그냥 plain string이냐에 따라 처리 방식이 다르다.

  • 이미 string이면 JSON.stringify()는 불필요하고, 오히려 문제를 일으킬 수 있다.

  • Content-Type을 정확하게 지정하는 게 중요하다:

    • JSON → application/json
    • 일반 텍스트 → text/plain

뱀발

최근 새 피쳐를 개발한 뒤에 우리 팀 서버 개발자가 실제 운영 DB에 들어온 데이터를 보더니 DB에 저장된 값에 ""가 붙어 있다며 ""를 빼달라고 했다.
난 분명 사용자가 input에 넣는 값에 별도로 ""를 넣은 적이 없고, 굳이 그걸 넣는 처리를 하는 게 더 귀찮기 때문에 그럴 리가 없다며 기능 구현부분을 봤는데 역시나 그런 처리를 한 적이 없었음.
그럼 통신할 때가 문제인가 싶어서 API 통신 구현부분을 봤더니 이미 데이터가 string인데 커서 이놈이 body에 넣을 거니까 JSON.stringify() 해놨던 듯.. 이건 다 커서가 자동완성으로 해준 탓이야 T_T!
아무튼 운영 데이터 자체도 2개 남짓으로 아직 몇 개 없었어서 데이터는 서버 개발자가 알아서 다시 처리를 해줬고, 프론트는 body 부분만 고쳐서 다시 배포했다 휴..

여하간에 이런 기본적인 실수를 할 줄이야.
호옥시나 잊지 않기 위해서 채찍피티의 도움을 받아서 기록을 해둔다.

profile
함께 나아가는 개발자💪

0개의 댓글