“Content-Type”, 서버는 내가 보낸 데이터를 어떻게 알아볼까?
들어가며
웹 개발을 하다 보면 이런 상황이 한 번쯤 생긴다.
분명히 서버에 데이터를 보냈는데 서버에서 제대로 읽지 못한다.
JSON으로 보냈다고 생각했는데 서버에서는 일반 문자열처럼 처리한다.
파일 업로드를 했는데 서버에서 파일 데이터가 이상하게 들어온다.
이럴 때 가장 먼저 확인해볼 만한 것 중 하나가 바로 Content-Type이다.
특히 API를 만들거나 다른 서비스의 API를 연동하다 보면 Content-Type 하나 때문에 몇 시간을 잡아먹는 경우도 있다. 코드만 계속 들여다보다가 개발자 도구의 Network 탭을 열어보면 의외로 원인이 바로 보이는 경우도 많다.
오늘은 Chrome 개발자 도구에서 Content-Type을 어떻게 확인하는지, 그리고 이 값이 실제로 어떤 역할을 하는지 정리해보려고 한다.
Content-Type이란 무엇일까?
Content-Type은 HTTP 메시지에 포함된 데이터가 어떤 형식인지 알려주는 정보다.
쉽게 말하면 서버에게 이렇게 이야기하는 것이다.
“내가 지금 보내는 데이터는 이런 종류야.”
대표적으로 웹 개발에서 자주 만나는 값은 다음과 같다.
Content-Type: application/json
JSON 데이터를 보낼 때 많이 사용한다.
Content-Type: application/x-www-form-urlencoded
HTML form 방식처럼 key=value 형태의 데이터를 보낼 때 사용한다.
Content-Type: multipart/form-data
파일 업로드처럼 여러 종류의 데이터를 하나의 요청으로 전송할 때 사용한다.
그리고 웹 페이지나 리소스를 응답받을 때도 Content-Type을 볼 수 있다.
Content-Type: text/html
HTML 문서라는 뜻이다.
Content-Type: text/css
CSS 파일이라는 뜻이고,
Content-Type: application/javascript
JavaScript 파일이라는 의미로 사용된다.
즉 Content-Type은 단순한 문자열 하나처럼 보이지만, HTTP 통신에서는 상당히 중요한 역할을 한다.
개발자 도구에서 Content-Type 확인하기
Chrome에서 확인하는 방법은 어렵지 않다.
먼저 확인하고 싶은 웹 페이지에서 F12를 눌러 개발자 도구를 연다.
그다음 Network 탭으로 이동한다.
페이지를 새로고침하면 브라우저가 서버에 요청한 여러 항목들이 쭉 나타난다.
HTML부터 CSS, JavaScript, 이미지, API 요청까지 상당히 많은 요청이 보일 수 있는데, 여기서 확인하고 싶은 요청을 클릭하면 된다.
그리고 오른쪽에서 Headers 항목을 확인한다.
여기에서 크게 두 부분을 살펴보면 된다.
Request Headers
브라우저가 서버로 요청을 보낼 때 함께 전달하는 헤더다.
API 요청이라면 다음과 같은 형태를 볼 수 있다.
Request Headers
Content-Type: application/json
Accept: application/json
이 경우 브라우저 또는 JavaScript 코드가 서버에 JSON 형식의 데이터를 보내고 있다는 것을 확인할 수 있다.
Response Headers
반대로 서버가 브라우저에게 응답을 보낼 때도 Content-Type을 전달한다.
예를 들어 API 서버가 JSON을 반환한다면 다음처럼 표시될 수 있다.
Response Headers
Content-Type: application/json
HTML 페이지라면 다음과 같이 표시될 수 있다.
Content-Type: text/html; charset=UTF-8
CSS라면 다음과 같은 식이다.
Content-Type: text/css
그래서 Content-Type을 확인할 때는 Request Headers인지 Response Headers인지 먼저 구분하는 것이 좋다.
JSON API를 디버깅할 때 특히 중요하다
개발하면서 Content-Type을 가장 자주 확인하게 되는 순간 중 하나가 API 요청을 디버깅할 때다.
예를 들어 JavaScript에서 다음과 같이 요청했다고 해보자.
fetch("/api/user", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "홍길동",
age: 30
})
});
여기서는 데이터를 JSON 문자열로 변환한 다음 서버로 보내고 있다.
개발자 도구의 Network 탭에서 해당 요청을 클릭하면 Request Headers에서
Content-Type: application/json
을 확인할 수 있다.
그리고 Payload 영역에서는 실제로 전달된 데이터를 확인할 수 있다.
{
"name": "홍길동",
"age": 30
}
이 두 가지를 같이 확인하면 상당히 편하다.
Headers에서는 어떤 형식으로 보냈는지 확인하고, Payload에서는 실제 어떤 데이터를 보냈는지 확인하는 것이다.
API가 정상적으로 동작하지 않을 때 이 두 곳을 먼저 확인하는 습관을 들이면 디버깅 시간이 꽤 줄어든다.
Content-Type과 Accept는 같은 것일까?
처음 보면 Content-Type과 Accept가 비슷해 보여서 헷갈리기 쉽다.
하지만 역할은 다르다.
Content-Type은 현재 보내거나 받는 데이터의 형식을 나타낸다.
반면 Accept는 클라이언트가 서버에게 어떤 형식의 응답을 원하는지 알려주는 값이다.
예를 들어 다음과 같은 요청이 있다고 해보자.
Content-Type: application/json
Accept: application/json
이것을 아주 단순하게 해석하면,
“나는 JSON 형식으로 데이터를 보내고 있고, 응답도 JSON으로 받고 싶어.”
정도로 이해할 수 있다.
둘을 혼동하면 API 요청을 만들 때 예상하지 못한 문제가 발생할 수 있기 때문에 개발자 도구에서 각각의 값을 구분해서 보는 것이 좋다.
파일 업로드에서는 Content-Type이 조금 다르다
파일 업로드를 해본 사람이라면 multipart/form-data라는 값을 본 적이 있을 것이다.
예를 들어 이미지 파일과 함께 이름 같은 추가 데이터를 서버로 보내는 경우다.
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary...
여기에서 뒤에 붙어 있는 boundary라는 값도 눈에 들어올 수 있다.
이것은 하나의 HTTP 요청 안에서 여러 데이터를 구분하기 위한 경계값이라고 생각하면 이해하기 쉽다.
파일 업로드가 제대로 되지 않을 때도 Network 탭에서 해당 요청을 열어 Content-Type과 Payload를 확인해보면 원인을 찾는 데 도움이 된다.
특히 파일 업로드 요청은 일반 JSON 요청과 구조가 다르기 때문에 단순히 application/json으로 처리하려고 하면 문제가 생길 수 있다.
Content-Type이 이상할 때 어디부터 확인할까?
API 요청이 예상과 다르게 처리된다면 나는 보통 다음 순서로 확인하는 편이다.
먼저 Network 탭에서 실제 요청을 찾는다.
그다음 Headers에서 Request URL과 Request Method를 확인한다.
그리고 Request Headers에서 Content-Type을 확인한다.
그 후 Payload를 확인해서 실제 전송 데이터가 예상한 형태인지 살펴본다.
마지막으로 Response와 Response Headers를 확인한다.
예를 들어 개발자가 JSON을 보내고 있다고 생각했는데 Network 탭에서
Content-Type: application/x-www-form-urlencoded
처럼 표시된다면 코드에서 데이터를 전송하는 방식부터 다시 확인해볼 필요가 있다.
반대로 서버는 JSON 응답을 보내야 하는데 Response Headers에서 전혀 다른 Content-Type이 나온다면 서버 쪽 응답 처리도 확인해야 한다.
이런 식으로 코드 → 실제 HTTP 요청 → 서버 응답을 연결해서 보면 문제가 훨씬 명확해진다.
Content-Type은 단순한 장식이 아니다
개발 초반에는 HTTP Header를 그냥 서버와 브라우저 사이에 붙어 다니는 부가 정보 정도로 생각하기 쉽다.
하지만 실제 프로젝트에서는 그렇지 않다.
인증 정보를 확인할 때도 헤더를 보고, 캐시 문제를 확인할 때도 헤더를 본다. 브라우저 종류를 확인할 때는 User-Agent를 보고, 데이터 형식을 확인할 때는 Content-Type을 확인한다.
결국 Network 탭의 Headers 영역은 브라우저와 서버가 실제로 어떤 이야기를 주고받았는지 확인할 수 있는 장소라고 생각하면 된다.
특히 “코드에서는 분명 JSON으로 보냈는데 왜 서버에서는 못 읽지?” 같은 문제가 생겼다면 코드만 계속 수정하기보다는 먼저 Network 탭을 열어보자.
실제로 서버에 전달된 Content-Type과 Payload를 확인해보면 생각보다 빨리 답이 나오는 경우가 많다.
웹 개발을 하면서 개발자 도구를 자주 사용하게 되는 이유도 바로 이런 부분에 있다. 브라우저 화면만 보고 있으면 보이지 않는 HTTP 통신 과정을 Network 탭에서는 직접 확인할 수 있기 때문이다.
다음에 API 요청이 이상하게 동작한다면 F12를 누르고 Network부터 열어보자.
그리고 가장 먼저 Headers의 Content-Type과 Payload를 확인해보는 것부터 시작하면 된다.
홍TV



![Eclipse에서 갑자기 "[m2e] Lifecycle Mapping" 오류? Maven 프로젝트가 빨간 줄 뜨는 이유 4 Eclipse에서 갑자기 [m2e] Lifecycle Mapping 오류? Maven 프로젝트가 빨간 줄 뜨는 진짜 이유](https://hongtv.co.kr/wp-content/uploads/2026/09/62edeb0f-aaf8-42cc-af31-1a91e54bc187-300x200.png)
댓글 0
첫 댓글을 남겨보세요.