사전 미디어 타입
표준

미디어 타입

gabury1고친 사람 github-actions[bot]

미디어 타입은 주고받는 데이터가 어떤 형식인지 알려 주는 이름표입니다. application/json 같은 짧은 문자열 하나로 받는 쪽이 읽는 방법을 고릅니다. 바이트만 봐서는 형식을 확신할 수 없어서 이 이름표를 따로 붙여 보냅니다. 웹과 전자메일이 이 이름표를 함께 씁니다.

쉽고 빠른 이해

미디어 타입은 데이터에 붙이는 형식 이름표입니다. 서버가 응답에 application/json 을 붙이면 클라이언트는 본문을 그 형식의 규칙대로 읽습니다.

이름표가 없으면 받는 쪽이 바이트를 보고 형식을 짐작해야 합니다. 짐작은 틀릴 수 있습니다. 같은 글자 덩어리가 웹 페이지로도 그냥 글자로도 읽힙니다.

어떻게 도나:

  1. 보내는 쪽이 본문의 형식을 이름표로 적어 헤더에 싣습니다
  2. 받는 쪽이 이름표를 읽고 맞는 해석기를 고릅니다
  3. 받을 수 있는 형식을 요청할 때 미리 알려 둘 수도 있습니다

본문을 실어 보낼 때는 늘 이름표를 붙입니다. 무슨 형식인지 모르면 「그냥 바이트」라는 뜻의 application/octet-stream 을 붙입니다.

대가가 있습니다. 이름표는 보내는 쪽의 말일 뿐이라 본문과 어긋날 수 있습니다. 어긋나면 본문이 엉뚱하게 읽히거나 요청이 거절됩니다.

상세

택배 상자에 붙은 「깨지기 쉬움」「냉장」 딱지를 떠올리면 됩니다. 배송 기사는 상자를 열지 않고 딱지만 보고 다루는 법을 정합니다. 미디어 타입도 본문을 열기 전에 읽는 딱지입니다. 택배 딱지는 사람이 눈으로 봅니다. 미디어 타입은 프로그램이 문자열로 비교합니다.

미디어 타입은 데이터 형식을 가리키는 표준 이름입니다. 예를 들어 text/html 은 HTML(HyperText Markup Language) 문서를 가리킵니다. image/png 는 PNG(Portable Network Graphics) 그림을 가리킵니다.

이름을 여럿이 같이 쓰려면 누가 어떤 이름을 쓰는지 한곳에 모아 두어야 합니다. 그 목록은 IANA(Internet Assigned Numbers Authority, 인터넷 번호 관리 기관)가 관리합니다. 목록에 이름을 올리는 일을 등록이라고 부릅니다.

RFC(Request for Comments)는 인터넷 표준을 담는 문서 묶음입니다. 이름을 등록하는 절차는 그중 RFC 6838 이 정합니다.

MIME 타입이라는 옛 이름

이 이름표는 전자메일에서 먼저 생겼습니다. 메일은 원래 글자만 나르도록 만들어져서 그림이나 첨부 파일을 실을 방법이 없었습니다. 그래서 본문 조각마다 형식을 적는 규칙을 더했습니다. 이 규칙 묶음이 MIME(Multipurpose Internet Mail Extensions, 다목적 인터넷 메일 확장)입니다.

HTTP(HyperText Transfer Protocol, 하이퍼텍스트 전송 프로토콜)가 이 이름표를 빌려 쓰면서 메일 밖으로 퍼졌습니다. 그래서 같은 것을 「MIME 타입」이라고도 부릅니다. 지금은 메일에 묶이지 않는 이름인 「미디어 타입」을 표준 용어로 씁니다. 헤더 이름을 따서 「콘텐츠 타입」이라 부르는 사람도 있습니다.

이름의 모양

미디어 타입은 슬래시로 나뉜 두 조각과 뒤에 붙는 매개변수로 이루어집니다. 앞 조각은 큰 분류입니다. 이 앞 조각을 최상위 타입이라 부릅니다. 뒤 조각은 그 안의 구체 형식이고 하위 타입이라 부릅니다. 매개변수는 형식 이름만으로 모자란 정보를 덧붙입니다.

flowchart TD
    A["text/html; charset=utf-8"] --> B["최상위 타입 · text"]
    A --> C["하위 타입 · html"]
    A --> D["매개변수 · charset=utf-8"]

위 그림의 문자열은 세 가지를 알립니다. 글자로 된 데이터입니다. 그중 HTML 입니다. 글자는 UTF-8(Unicode Transformation Format 8비트)로 적혀 있습니다.

최상위 타입과 하위 타입 이름은 대소문자를 가리지 않습니다. Text/HTML 과 text/html 은 같은 이름입니다.

최상위 타입

최상위 타입은 받는 쪽이 하위 타입을 몰라도 대강 어떻게 다룰지 정하게 해 줍니다. 처음 보는 text/어떤것 을 받아도 글자로 보여 줄 수는 있습니다. 자주 만나는 최상위 타입은 아래와 같습니다.

최상위 타입 담는 것 예
text 사람이 읽을 수 있는 글자 text/plain · text/html · text/csv
image 그림 image/png · image/jpeg
audio 소리 audio/mpeg
video 영상 video/mp4
application 프로그램이 해석해야 하는 데이터 application/json · application/pdf
multipart 여러 조각을 한 본문에 묶은 것 multipart/form-data

application 은 나머지를 받는 넓은 분류입니다. JSON(JavaScript Object Notation)처럼 글자로 적혀 있어도 프로그램이 규칙대로 읽어야 하는 형식이 여기 들어갑니다. 무슨 형식인지 모르는 바이트 덩어리에는 application/octet-stream 을 붙입니다. 「그냥 바이트」라는 뜻이라 받는 쪽은 대개 해석하지 않고 파일로 내려받습니다.

매개변수

매개변수는 세미콜론 뒤에 이름=값 꼴로 붙습니다. 형식은 같은데 읽는 데 필요한 정보가 더 있을 때 씁니다. 대표가 글자의 문자 인코딩을 알리는 charset 입니다.

multipart 타입에는 boundary 매개변수가 붙습니다. 여러 조각을 한 본문에 이어 붙이면 어디서 조각이 끊기는지 알려야 합니다. boundary 의 값이 조각 사이에 끼워 넣는 구분자 문자열입니다.

http
Content-Type: multipart/form-data; boundary=XyZ

조각 사이의 경계 줄은 구분자 앞에 하이픈 둘을 붙여 적습니다. 그래서 이 헤더를 받은 쪽은 본문에서 --XyZ 가 나오는 줄마다 조각을 자릅니다. 파일 올리기 폼이 이 방식으로 파일과 입력값을 한 요청에 싣습니다.

등록 트리

이름이 부딪히지 않으려면 누가 만든 이름인지 구분해야 합니다. 그래서 하위 타입 이름 앞에 접두사를 붙여 등록 갈래를 나눕니다. 이 갈래를 트리라고 부릅니다.

트리 하위 타입 모양 쓰는 경우
표준 트리 접두사 없음 · application/json 표준 문서로 정한 형식
벤더 트리 vnd. 로 시작 회사나 제품이 만든 형식
개인 트리 prs. 로 시작 개인이나 실험용 형식
미등록 x. 로 시작 (옛 표기 x-) 등록하지 않고 쓰는 이름

x. 와 x- 는 둘 다 미등록 이름을 나타냅니다. x- 는 예전에 널리 쓰던 표기이고, x. 는 뒤에 트리 규칙에 맞춰 정한 표기입니다. 예전 x- 이름은 널리 퍼진 뒤에 등록 이름으로 바꾸기 어려웠습니다. 그래서 지금은 새 형식에 둘 다 쓰지 말고 벤더 트리나 개인 트리에 등록하라고 권합니다.

구조 접미사

하위 타입 끝에 +json 이나 +xml 이 붙는 이름이 있습니다. 이것을 구조 접미사라고 부릅니다. 「이 형식은 따로 이름이 있지만 속은 JSON 문법으로 적혀 있다」는 뜻입니다.

예를 들어 application/problem+json 은 HTTP 오류 응답을 담는 형식입니다. 이 형식을 모르는 클라이언트도 접미사를 보고 JSON 해석기로 일단 열 수는 있습니다. XML(Extensible Markup Language)로 적힌 형식에는 같은 이유로 +xml 을 붙입니다.

HTTP 에서 이름표가 오가는 방식

HTTP 는 두 헤더로 미디어 타입을 주고받습니다. Content-Type 은 「내가 보내는 본문은 이 형식이다」를 알립니다. Accept 는 「나는 이런 형식으로 받고 싶다」를 요청에 적습니다.

sequenceDiagram
    participant 클라이언트
    participant 서버
    클라이언트->>서버: 요청 · Accept 에 받을 형식을 적는다
    Note over 서버: 줄 수 있는 형식 가운데 하나를 고른다
    서버-->>클라이언트: 응답 · Content-Type 에 고른 형식을 적는다

서버가 여러 형식을 줄 수 있을 때 Accept 를 보고 하나를 고르는 일을 콘텐츠 협상이라고 부릅니다. 같은 주소가 브라우저에는 HTML 을, API(Application Programming Interface) 클라이언트에는 JSON 을 돌려줄 수 있습니다. Accept 에는 여러 형식을 선호도와 함께 적을 수 있습니다.

http
Accept: application/json, text/html;q=0.5

q 는 0 부터 1 사이의 선호도입니다. q 를 안 적으면 1 로 칩니다. 그래서 위 헤더는 JSON 을 먼저 원한다는 뜻입니다. JSON 이 안 되면 HTML 도 받습니다.

형식 이름 대신 별표를 쓰면 「무엇이든 받는다」가 됩니다. 아래처럼 */* 를 낮은 선호도로 덧붙이면 남은 형식도 받겠다는 뜻입니다.

http
Accept: application/json, */*;q=0.1

이름표가 어긋날 때

요청 본문의 형식을 서버가 처리할 수 없으면 서버는 HTTP 415(Unsupported Media Type)로 거절합니다. JSON 을 받는 API 에 Content-Type 없이 본문을 보내면 흔히 이 응답을 받습니다. 반대로 Accept 에 적힌 형식을 하나도 줄 수 없을 때 쓰는 응답은 HTTP 406(Not Acceptable)입니다.

이름표와 본문이 다를 때 받는 쪽이 바이트를 보고 형식을 다시 짐작하는 동작을 MIME 스니핑이라고 부릅니다. 짐작 덕분에 잘못 붙은 이름표를 넘길 수 있습니다.

짐작은 보안 문제를 부르기도 합니다. 사용자가 글자 파일로 올린 데이터를 브라우저가 스크립트로 짐작하면, 다른 사용자가 그 파일을 열 때 올린 사람이 심은 코드가 실행됩니다. 이를 막으려고 서버가 X-Content-Type-Options 헤더에 nosniff 를 적습니다. 그러면 브라우저가 짐작하지 않고 이름표대로만 읽습니다.

파일 확장자와의 차이

파일 이름 끝의 .json 이나 .png 도 형식을 알리는 표시입니다. 하지만 확장자는 파일 이름의 일부일 뿐이라 누구나 바꿀 수 있습니다. 네트워크로 오가는 데이터에는 파일 이름이 아예 없을 때가 많습니다.

그래서 웹 서버는 파일을 내보낼 때 확장자를 보고 미디어 타입을 찾아 헤더에 적습니다. 확장자와 미디어 타입을 짝지은 표를 서버가 들고 있는 셈입니다. 받는 쪽은 확장자가 아니라 헤더의 미디어 타입을 보고 해석합니다.

관련 항목

미디어 타입을 싣는 HTTP 헤더

Content-Type · Accept · Content-Disposition · X-Content-Type-Options · Accept-Charset · Content-Encoding

미디어 타입이 속하는 상위 분류

메타데이터 · 표현 · HTTP · MIME · RFC 9110 · 전자메일

미디어 타입을 정하고 등록하는 표준·기관

IANA · RFC 6838 · RFC 2045 · RFC 2046 · RFC 6839 · RFC 9457

미디어 타입 이름을 이루는 구성 요소

최상위 타입 · 하위 타입 · 매개변수 · 문자셋 · boundary · 구조 접미사 · +xml 접미사 · 벤더 트리

미디어 타입으로 이름 붙는 형식

application/json · application/xml · text/xml · application/octet-stream · multipart/form-data · application/x-www-form-urlencoded · text/html · text/plain · application/problem+json

미디어 타입을 보고 형식을 고르는 처리 단계

콘텐츠 협상 · MIME 스니핑 · 파싱 · 역직렬화 · 파일 확장자 · 매직 넘버

미디어 타입에서 자주 나는 오류

HTTP 415 · HTTP 406 · 문자 깨짐 · 콘텐츠 스니핑 공격

미디어 타입이 가리키는 데이터 형식

JSON · XML · HTML · CSV · PNG · PDF · 문자 인코딩 · 직렬화

다른 이름: media type · MIME 타입 · MIME type