HTTP Content-Type 헤더: 완벽 가이드 (2026)
개발자가 Content-Type 헤더에 대해 알아야 할 모든 것
Hypereal로 구축 시작하기
단일 API를 통해 Kling, Flux, Sora, Veo 등에 액세스하세요. 무료 크레딧으로 시작하고 수백만으로 확장하세요.
신용카드 불필요 • 10만 명 이상의 개발자 • 엔터프라이즈 지원
HTTP Content-Type Header: 완벽 가이드 (2026)
Content-Type 헤더는 가장 중요한 HTTP 헤더 중 하나입니다. 이 헤더는 서버(또는 클라이언트)에게 요청 또는 응답 본문에 어떤 유형의 데이터가 포함되어 있는지 알려주어, 데이터를 어떻게 파싱하고 처리해야 할지 판단하게 합니다. Content-Type을 잘못 설정하면 415 Unsupported Media Type, 잘못된 형식의 JSON, 파일 업로드 실패, 텍스트 깨짐 등 가장 흔한 API 오류들이 발생합니다.
이 가이드에서는 MIME 타입부터 주요 프로그래밍 언어 및 프레임워크에서의 실무 예제까지, Content-Type에 대해 알아야 할 모든 내용을 다룹니다.
Content-Type 헤더란 무엇인가요?
Content-Type 헤더는 리소스의 미디어 타입(MIME 타입이라고도 함)이나 요청 또는 응답 본문의 데이터 유형을 나타내는 HTTP 엔티티 헤더입니다. 다음과 같은 형식을 따릅니다.
Content-Type: type/subtype; parameter=value
예시:
Content-Type: application/json; charset=utf-8
Content-Type: text/html; charset=utf-8
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
세 가지 구성 요소
| 구성 요소 | 설명 | 예시 |
|---|---|---|
| Type | 일반적인 범주 | application, text, image, audio, video, multipart |
| Subtype | 구체적인 형식 | json, html, png, mp4, form-data |
| Parameters | 추가적인 메타데이터 (선택 사항) | charset=utf-8, boundary=xxx |
자주 사용되는 Content-Type 값
웹 개발 및 API에서 가장 자주 사용되는 Content-Type 값들을 정리한 참조 표입니다.
텍스트 타입 (Text Types)
| Content-Type | 용도 |
|---|---|
text/plain |
서식이 없는 일반 텍스트 |
text/html |
HTML 문서 |
text/css |
CSS 스타일시트 |
text/javascript |
JavaScript 파일 |
text/csv |
쉼표로 구분된 값 (CSV) |
text/xml |
XML 문서 (application/xml 권장) |
애플리케이션 타입 (Application Types)
| Content-Type | 용도 |
|---|---|
application/json |
JSON 데이터 (API에서 가장 흔히 사용) |
application/xml |
XML 데이터 |
application/x-www-form-urlencoded |
HTML 폼 데이터 (기본값) |
application/octet-stream |
이진 데이터 (일반적 용도) |
application/pdf |
PDF 문서 |
application/zip |
ZIP 압축 파일 |
application/gzip |
Gzip 압축 데이터 |
application/graphql+json |
GraphQL 요청 |
멀티파트 타입 (Multipart Types)
| Content-Type | 용도 |
|---|---|
multipart/form-data |
파일 업로드 및 파일이 포함된 폼 데이터 |
multipart/mixed |
단일 메시지 내 혼합된 콘텐츠 타입 |
multipart/alternative |
동일한 콘텐츠의 다른 형식 (이메일 등) |
이미지 타입 (Image Types)
| Content-Type | 용도 |
|---|---|
image/png |
PNG 이미지 |
image/jpeg |
JPEG 이미지 |
image/gif |
GIF 이미지 |
image/webp |
WebP 이미지 |
image/svg+xml |
SVG 벡터 이미지 |
image/avif |
AVIF 이미지 |
오디오 및 비디오 타입 (Audio and Video Types)
| Content-Type | 용도 |
|---|---|
audio/mpeg |
MP3 오디오 |
audio/wav |
WAV 오디오 |
audio/ogg |
OGG 오디오 |
video/mp4 |
MP4 비디오 |
video/webm |
WebM 비디오 |
상황별 Content-Type 사용법
application/json
REST API에서 가장 흔히 사용되는 Content-Type입니다. 구조화된 데이터를 주고받을 때마다 사용하세요.
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com"}'
application/x-www-form-urlencoded
HTML <form> 제출 시의 기본 Content-Type입니다. 데이터는 &로 구분된 키-값 쌍으로 인코딩됩니다.
curl -X POST https://api.example.com/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=john&password=secret123"
요청 본문에서의 데이터 형식은 다음과 같습니다.
username=john&password=secret123
특수 문자는 퍼센트 인코딩됩니다(예: 공백은 + 또는 %20으로 변환).
multipart/form-data
파일 업로드 시 필수적입니다. 각 필드는 자체 Content-Type을 가진 개별 파트로 전송됩니다.
curl -X POST https://api.example.com/upload \
-H "Content-Type: multipart/form-data" \
-F "file=@photo.jpg" \
-F "description=My vacation photo"
프로그래밍 언어별 Content-Type 설정 방법
JavaScript (Fetch API)
// JSON 요청
const response = await fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'John', email: 'john@example.com' }),
});
// 폼 데이터 (Content-Type이 자동으로 설정됨)
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('name', 'John');
const response = await fetch('https://api.example.com/upload', {
method: 'POST',
// FormData를 사용할 때는 Content-Type을 수동으로 설정하지 마세요.
// 브라우저가 올바른 boundary를 포함하여 자동으로 설정합니다.
body: formData,
});
Python (Requests)
import requests
# JSON 요청 (json= 매개변수 사용 시 Content-Type이 자동으로 설정됨)
response = requests.post(
'https://api.example.com/data',
json={'name': 'John', 'email': 'john@example.com'}
)
# Form-urlencoded (data= 매개변수 사용 시 자동으로 설정됨)
response = requests.post(
'https://api.example.com/login',
data={'username': 'john', 'password': 'secret123'}
)
# 파일 업로드 (files= 매개변수 사용 시 Content-Type이 자동으로 설정됨)
with open('photo.jpg', 'rb') as f:
response = requests.post(
'https://api.example.com/upload',
files={'file': ('photo.jpg', f, 'image/jpeg')},
data={'description': 'My vacation photo'}
)
# 명시적 Content-Type 설정
response = requests.post(
'https://api.example.com/data',
headers={'Content-Type': 'application/xml'},
data='<user><name>John</name></user>'
)
Go
package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
// JSON 요청
data := map[string]string{"name": "John", "email": "john@example.com"}
jsonData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api.example.com/data",
bytes.NewBuffer(jsonData))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
}
cURL
# JSON
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-d '{"name": "John"}'
# 폼 데이터
curl -X POST https://api.example.com/login \
-d "username=john&password=secret"
# 파일 업로드
curl -X POST https://api.example.com/upload \
-F "file=@photo.jpg" \
-F "description=My photo"
# 이진 데이터
curl -X POST https://api.example.com/binary \
-H "Content-Type: application/octet-stream" \
--data-binary @file.bin
API 응답에서의 Content-Type
클라이언트가 데이터를 올바르게 파싱할 수 있도록 서버 또한 응답에 정확한 Content-Type을 설정해야 합니다.
Express.js
app.get('/api/users', (req, res) => {
// res.json()은 자동으로 Content-Type: application/json을 설정합니다.
res.json({ users: [] });
});
app.get('/report.pdf', (req, res) => {
res.setHeader('Content-Type', 'application/pdf');
res.sendFile('/path/to/report.pdf');
});
app.get('/page', (req, res) => {
// 문자열과 함께 res.send()를 사용하면 Content-Type: text/html이 설정됩니다.
res.send('<h1>Hello</h1>');
});
FastAPI (Python)
from fastapi import FastAPI
from fastapi.responses import JSONResponse, HTMLResponse, StreamingResponse
app = FastAPI()
@app.get("/api/users")
async def get_users():
# 기본적으로 application/json을 반환합니다.
return {"users": []}
@app.get("/page", response_class=HTMLResponse)
async def get_page():
return "<h1>Hello</h1>"
@app.get("/download")
async def download_file():
return StreamingResponse(
open("file.pdf", "rb"),
media_type="application/pdf"
)
charset 매개변수
charset 매개변수는 텍스트 콘텐츠의 문자 인코딩을 지정합니다. 특별한 이유가 없다면 항상 표준인 UTF-8을 사용해야 합니다.
Content-Type: text/html; charset=utf-8
Content-Type: application/json; charset=utf-8
참고: JSON 명세(RFC 8259)에 따르면 JSON은 반드시 UTF-8로 인코딩되어야 합니다. 기술적으로 application/json에 charset 매개변수는 불필요하지만, 명확성을 위해 많은 API가 이를 포함합니다.
Content-Type vs. Accept 헤더
이 두 헤더는 종종 혼동됩니다.
| 헤더 | 목적 | 사용 위치 | 방향 |
|---|---|---|---|
Content-Type |
본문의 형식을 설명 | 요청 및 응답 | "내가 보내는 데이터의 형식" |
Accept |
특정 형식을 요청함 | 요청에만 사용 | "내가 받고 싶은 데이터의 형식" |
# "JSON을 보낼 테니, JSON으로 응답해 주세요."
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name": "John"}'
흔한 오류 및 해결 방법
415 Unsupported Media Type
서버가 사용자가 보낸 Content-Type을 수락하지 않습니다.
# 오류: JSON 전용 엔드포인트에 폼 데이터를 보냄
curl -X POST https://api.example.com/data \
-d "name=John"
# 해결: 대신 JSON을 전송
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-d '{"name": "John"}'
400 Bad Request (Malformed JSON)
Content-Type은 JSON이라고 되어 있지만, 본문이 유효한 JSON 형식이 아닙니다.
# 오류: 유효하지 않은 JSON
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-d "name=John"
# 해결: 올바른 JSON 문법 사용
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-d '{"name": "John"}'
FormData 사용 시 파일 업로드 실패
JavaScript에서 FormData를 사용할 때 Content-Type을 수동으로 설정하지 마세요. 브라우저가 올바른 boundary 문자열을 포함하여 설정해야 합니다.
// 오류
const formData = new FormData();
formData.append('file', file);
fetch('/upload', {
method: 'POST',
headers: { 'Content-Type': 'multipart/form-data' }, // 이렇게 하지 마세요
body: formData,
});
// 올바른 방법
fetch('/upload', {
method: 'POST',
// 브라우저가 boundary를 포함한 Content-Type을 설정하도록 둡니다.
body: formData,
});
콘텐츠 협상 (Content Negotiation)
일부 API는 여러 응답 형식을 지원합니다. 클라이언트는 Accept 헤더를 사용하여 특정 형식을 요청하고, 서버는 응답의 Content-Type을 통해 전송한 형식을 확인해 줍니다.
# XML 응답 요청
curl -H "Accept: application/xml" https://api.example.com/users
# JSON 응답 요청
curl -H "Accept: application/json" https://api.example.com/users
마치며
Content-Type 헤더는 HTTP 통신의 작동 방식에 있어 핵심적인 요소입니다. 이를 올바르게 설정하면 서버와 클라이언트가 데이터를 적절히 파싱하고, 파일 업로드가 정상적으로 작동하며, API가 올바른 형식을 반환하도록 보장할 수 있습니다. 대부분의 현대적인 프레임워크는 일반적인 경우(JSON, 폼 데이터)에 대해 Content-Type을 자동으로 처리해 주지만, 그 원리를 이해하면 필연적으로 발생하는 예외 상황을 디버깅하는 데 큰 도움이 됩니다.
이미지, 비디오, 오디오 또는 말하는 아바타와 같은 AI 생성 미디어를 활용하는 애플리케이션을 구축하고 있다면, Hypereal AI를 확인해 보세요. 복잡한 처리를 대신 수행하며 올바른 Content-Type 헤더와 함께 미디어를 반환하는 통합 API를 제공합니다.
Hypereal AI 무료 체험하기 -- 신용카드 없이 35 크레딧 제공
