오늘은 fetch로 POST나 PATCH 요청을 보낼 때, body에 문자열을 어떻게 다뤄야 하는지 정리해본다.
가장 기본적인 케이스.
const data = { name: 'Alice' }
fetch('/api/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // ✅ 꼭 stringify 해줘야 함
})
이미 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\\\"}\"" 이런 괴상한 문자열이 전송됨
단순 문자열을 보낼 때도 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\"" 전송됨
function isValidJSON(str: string) {
try {
JSON.parse(str)
return true
} catch {
return false
}
}
body에 들어가는 건 항상 string이어야 하지만,
그게 JSON string이냐, 그냥 plain string이냐에 따라 처리 방식이 다르다.
이미 string이면 JSON.stringify()는 불필요하고, 오히려 문제를 일으킬 수 있다.
Content-Type을 정확하게 지정하는 게 중요하다:
application/jsontext/plain최근 새 피쳐를 개발한 뒤에 우리 팀 서버 개발자가 실제 운영 DB에 들어온 데이터를 보더니 DB에 저장된 값에 ""가 붙어 있다며 ""를 빼달라고 했다.
난 분명 사용자가 input에 넣는 값에 별도로 ""를 넣은 적이 없고, 굳이 그걸 넣는 처리를 하는 게 더 귀찮기 때문에 그럴 리가 없다며 기능 구현부분을 봤는데 역시나 그런 처리를 한 적이 없었음.
그럼 통신할 때가 문제인가 싶어서 API 통신 구현부분을 봤더니 이미 데이터가 string인데 커서 이놈이 body에 넣을 거니까 JSON.stringify() 해놨던 듯.. 이건 다 커서가 자동완성으로 해준 탓이야 T_T!
아무튼 운영 데이터 자체도 2개 남짓으로 아직 몇 개 없었어서 데이터는 서버 개발자가 알아서 다시 처리를 해줬고, 프론트는 body 부분만 고쳐서 다시 배포했다 휴..
여하간에 이런 기본적인 실수를 할 줄이야.
호옥시나 잊지 않기 위해서 채찍피티의 도움을 받아서 기록을 해둔다.