Quick Reference
POST /api/orders HTTP/1.1
Content-Type: application/json
Accept: application/json
{
"sku": "book-001",
"quantity": 1
}전송 기준
Content-Type은 요청 본문의 형식을 말한다
HTTP 요청에서 Content-Type: application/json은 본문이 JSON text라는 계약이다. 서버는 이 header를 보고 JSON parser를 적용할지 판단한다. 본문은 JSON인데 text/plain이나 잘못된 media type으로 보내면 서버 프레임워크가 body parser를 실행하지 않거나, 원시 문자열로만 처리할 수 있다.
Content-Type: application/json파일 확장자나 URL이 .json인지보다 실제 HTTP header가 중요하다. 특히 API 클라이언트, webhook, form 제출을 섞어 쓰는 환경에서는 Content-Type 불일치가 흔한 원인이다.
Accept는 응답으로 받고 싶은 형식을 말한다
Accept: application/json은 클라이언트가 JSON 응답을 기대한다는 뜻이다. Content-Type은 보내는 본문, Accept는 받고 싶은 응답 형식이므로 서로 다른 방향의 header다. GET 요청처럼 body가 없는 요청에서도 Accept는 의미가 있지만, Content-Type은 보낼 본문이 없으면 보통 필요하지 않다.
media type과 charset은 JSON body 계약의 일부다
RFC 8259의 media type 등록은 application/json에 charset parameter를 정의하지 않으며, 개방형 시스템에서 JSON text는 UTF-8로 보냅니다. application/json; charset=utf-8을 받는 구현은 많지만, sender와 receiver가 실제 UTF-8 body를 같은 JSON parser로 처리하는지가 핵심입니다. application/problem+json처럼 +json suffix를 가진 media type도 JSON 문법을 쓰지만, 응답 의미는 각 media type의 별도 규격을 따릅니다.
빈 응답과 JSON null은 다르다
HTTP 204처럼 본문이 없는 응답은 JSON 값이 아닙니다. 반면 null은 유효한 JSON 값입니다. 클라이언트에서 모든 응답에 무조건 response.json()을 호출하면 빈 body에서 파싱 오류가 날 수 있습니다. Content-Length는 chunked response에서 없을 수 있으므로 status code와 media type, 실제 body 소비 정책을 함께 봅니다.
체크포인트
| 상황 | 확인할 것 |
|---|---|
| JSON 요청 전송 | Content-Type: application/json |
| JSON 응답 기대 | Accept: application/json |
| 204·205 또는 빈 body 계약 | JSON parser 호출하지 않음 |
| HTML 에러 페이지 수신 | 응답 Content-Type과 status 먼저 확인 |
| webhook 수신 실패 | header와 실제 body가 일치하는지 확인 |
공식 참고: RFC 8259: JSON, RFC 9110: HTTP Semantics
주의할 점
응답 status가 성공이어도 body가 JSON이라는 보장은 없습니다. 인증 실패, 프록시 오류,
서버 예외에서 HTML이 내려오면 JSON parser가 실패합니다. 먼저 Content-Type을 확인하고
그 다음 parser를 호출하는 흐름이 안전합니다.
const response = await fetch("/api/orders");
if (response.status === 204 || response.status === 205) {
return null;
}
const contentType = response.headers.get("content-type") ?? "";
const mediaType = contentType.split(";", 1)[0].trim().toLowerCase();
if (mediaType !== "application/json" && !mediaType.endsWith("+json")) {
throw new Error("Expected JSON response");
}
return response.json();참고 링크
2 sources