Content-Type w tworzeniu stron internetowych: co to jest, typy MIME i jak działa

Autor: IT Sectr Opublikowano: 2026-03-10 Czas czytania: 9 min

Content-Type — to nagłówek HTTP, który określa, w jakim formacie przesyłane są dane między klientem a serwerem. Bez prawidłowego typu MIME przeglądarka nie może poprawnie przetworzyć odpowiedzi: plik tekstowy wyświetla się jako surowy kod, a obraz nie otwiera się. Według MDN Web Docs, 2025, Content-Type jest obowiązkowy do prawidłowego przesyłania danych dowolnego typu w protokole HTTP i określa, jak odbiorca interpretuje treść wiadomości.

Najważniejsze

  • Content-Type — nagłówek HTTP określający typ MIME przesyłanych danych w treści żądania lub odpowiedzi.
  • Typ MIME składa się z głównej kategorii i podtypu, rozdzielonych ukośnikiem — na przykład text/html lub application/json.
  • Parametr charset określa kodowanie dla tekstowych typów MIME, standardem dla sieci jest UTF-8.
  • Bez Content-Type przeglądarka włącza MIME sniffing, co prowadzi do błędów wyświetlania i luk bezpieczeństwa.
  • Nagłówek X-Content-Type-Options: nosniff wyłącza zgadywanie typu i zwiększa bezpieczeństwo aplikacji webowych.

Co to jest Content-Type?

Content-Type — to nagłówek HTTP z grupy nagłówków reprezentacji (representation headers), który informuje odbiorcę o formacie danych w treści wiadomości. Jest obowiązkowy dla żądań i odpowiedzi HTTP zawierających treść (body), a bez niego klient nie może poprawnie zinterpretować otrzymanych bajtów. Przeglądarka lub aplikacja mobilna na podstawie Content-Type wybiera parser: dla text/html uruchamia silnik HTML, dla image/png — dekoder PNG, dla application/json — parser JSON.

Wartość Content-Type to typ MIME — standaryzowany identyfikator formatu danych. Skrót MIME oznacza Multipurpose Internet Mail Extensions, ponieważ standard ten został pierwotnie stworzony dla załączników e-mail. Stał się jednak podstawą HTTP i jest dziś używany powszechnie — od przesyłania stron internetowych po wymianę danych w REST API. Każdy typ MIME składa się z dwóch części: głównej kategorii i uszczegóławiającego podtypu, rozdzielonych ukośnikiem.

Parametr charset uzupełnia Content-Type dla formatów tekstowych. Na przykład Content-Type: text/html; charset=utf-8 oznacza, że przesyłany jest dokument HTML w kodowaniu UTF-8. Według IETF RFC 7231, sekcja 3.1.1.5, nagłówek Content-Type jest obowiązkowy dla wiadomości HTTP zawierających treść, a jego brak jest interpretowany jako application/octet-stream lub prowadzi do MIME sniffing.

Historia pojawienia się typów MIME w HTTP

Protokół HTTP/0.9, wydany w 1991 roku, przesyłał tylko strony HTML, więc typ danych był domyślnie określony. Wraz z pojawieniem się HTTP/1.0 w specyfikacji RFC 1945 twórcy zdali sobie sprawę z konieczności przesyłania obrazów, arkuszy stylów i skryptów. Zaadaptowali standard MIME z protokołu e-mail, a Content-Type stał się nieodłączną częścią HTTP. Od tego czasu rejestr IANA rozszerzył się do setek wartości — od znanych text/html po współczesne image/avif i application/manifest+json.

Rola Content-Type w bezpieczeństwie

Content-Type odgrywa kluczową rolę w ochronie przed atakami. Jeśli serwer wysyła plik HTML z typem MIME text/plain, przeglądarka nie będzie wykonywać JavaScript i budować DOM — zapobiega to atakom XSS. Nagłówek X-Content-Type-Options: nosniff, zalecany przez OWASP, całkowicie zabrania przeglądarce zgadywania typu MIME na podstawie zawartości. Według PortSwigger Research, ataki z wykorzystaniem MIME sniffing były szczególnie rozpowszechnione w Internet Explorer 6-9, gdzie przeglądarka ignorowała Content-Type i określała typ na podstawie pierwszych bajtów pliku.

Struktura typu MIME

Typ MIME jest określany w formacie type/subtype, gdzie type to ogólna kategoria danych, a subtype to konkretny format w jej obrębie. Na przykład w wartości image/png kategoria image wskazuje na obraz, a podtyp png — na format Portable Network Graphics. Kategorii jest zaledwie kilka: text, image, audio, video, application, multipart i message. Resztę różnorodności zapewniają podtypy, których są setki.

Dodatkowe parametry są przekazywane przez średnik po podtypie. Najpopularniejszym parametrem jest charset do określania kodowania. Content-Type: application/json; charset=utf-8 informuje, że przesyłany jest dokument JSON w kodowaniu UTF-8. Formalnie charset dla application/json jest zbędny, ponieważ JSON zawsze jest w UTF-8 zgodnie ze specyfikacją RFC 8259, ale jawne określenie poprawia kompatybilność ze starymi klientami HTTP.

KategoriaPrzykłady podtypówOpis
texthtml, plain, css, javascript, csvFormaty tekstowe czytelne dla człowieka
imagejpeg, png, gif, webp, svg+xml, avifObrazy rastrowe i wektorowe
audiompeg, ogg, wav, mp4, webmFormaty audio do strumieniowego odtwarzania
videomp4, webm, ogg, x-msvideo, 3gppFormaty wideo i kontenery multimedialne
applicationjson, xml, pdf, zip, octet-stream, protobufDane binarne i strukturyzowane
multipartform-data, mixed, alternative, byterangesDokumenty złożone z wielu części

Standardowe i niestandardowe typy MIME

Standardowe typy MIME są rejestrowane w rejestrze IANA i mają prefiks głównej kategorii. Niestandardowe (vendor-specific) używają prefiksu x- lub formatu vnd.company.type — na przykład application/vnd.google-earth.kml+xml dla formatu KML od Google. Przeglądarki mogą nie rozpoznawać niestandardowych typów, dlatego dla nieznanych załączników używany jest application/octet-stream — uniwersalny strumień binarny, którego przeglądarka nie próbuje wyświetlić, ale oferuje pobranie jako pliku.

Parametr charset w praktyce

Parametr charset jest krytyczny dla poprawnego wyświetlania tekstu. Bez niego przeglądarka może nieprawidłowo zinterpretować znaki, co prowadzi do krzaków (mojibake). Dla sieci standardem jest UTF-8, ale spotyka się ISO-8859-1 (Latin-1) dla języków zachodnioeuropejskich i windows-1251 dla cyrylicy na starych stronach. Zalecenie W3C — zawsze określać charset=utf-8 dla text/html i text/plain, a dla application/json charset nie jest wymagany.

Główne typy Content-Type

W praktyce twórcy stron internetowych i programiści mobilni pracują z ograniczonym zestawem typów MIME. Znajomość tych typów jest niezbędna do prawidłowej konfiguracji serwera, pisania klientów HTTP i obsługi plików statycznych. text/html — podstawowy typ dla stron internetowych, zwracany domyślnie przez serwery Apache i Nginx dla plików HTML. application/xhtml+xml jest używany rzadziej i tylko dla dokumentów XHTML.

application/json stał się standardem dla REST API. Serwery zwracają dane JSON z tym typem MIME, a klienci wysyłają go w żądaniach POST i PUT. text/javascript (przestarzały) i application/javascript są używane dla plików JavaScript. Według W3Techs Survey, 2025, JSON jest najszybciej rosnącym formatem danych w sieci, wyprzedzając XML w 2018 roku. Dla usług SOAP wciąż stosuje się text/xml lub application/soap+xml.

Dla obrazów typ MIME jest określany przez format pliku: image/jpeg dla JPEG, image/png dla PNG, image/gif dla GIF, image/webp dla nowoczesnego formatu WebP. image/svg+xml jest używany dla grafiki wektorowej i obsługuje osadzone style i skrypty. video/mp4, audio/mpeg i application/pdf — inne często spotykane typy. Dla czcionek internetowych używa się font/woff2, font/woff i font/ttf.

Content-Type przy przesyłaniu plików

Przy wysyłaniu plików przez formularz HTML używany jest multipart/form-data — złożony typ MIME, który dzieli żądanie na kilka części. Każda część ma własny nagłówek Content-Type i Content-Disposition, wskazujący nazwę pola i oryginalną nazwę pliku. Serwer otrzymuje plik z jego rzeczywistym typem MIME, określonym przez przeglądarkę, i może go zweryfikować po stronie backendu. application/octet-stream jest stosowany dla plików nieznanego typu — przeglądarka nie próbuje wyświetlić zawartości, ale oferuje zapisanie jej na dysku.

Wpływ Content-Type na buforowanie

Typ MIME wpływa na politykę buforowania CDN i przeglądarki. Obrazy ze stabilnymi URL-ami są zwykle buforowane na długi okres (rok i dłużej), podczas gdy strony HTML — na minuty lub sekundy. Serwery CDN Cloudflare i Akamai używają Content-Type do wyboru algorytmu kompresji: text/* jest kompresowany gzip lub brotli, image/* — nie, ponieważ obrazy są już skompresowane. Prawidłowa konfiguracja Content-Type na serwerze bezpośrednio wpływa na wydajność ładowania stron i aplikacji mobilnych.

Jak serwer i klient używają Content-Type

Serwer ustawia nagłówek Content-Type w odpowiedzi HTTP na podstawie typu żądanego pliku lub dynamicznie wygenerowanej treści. Popularne serwery www Nginx i Apache mają wbudowane tablice typów MIME, które mapują rozszerzenie pliku na odpowiedni Content-Type. Na przykład plik index.html otrzymuje text/html, a style.css — text/css. Dla odpowiedzi dynamicznych programista określa Content-Type w kodzie aplikacji w PHP, Python, Java lub Kotlin.

Klient używa Content-Type do wyboru obsługi. Jeśli serwer zwraca text/html, przeglądarka uruchamia parser HTML i buduje drzewo DOM. Jeśli image/png — uruchamia dekoder PNG. Jeśli Content-Type jest nieobecny lub nieprawidłowy, klient stosuje MIME sniffing — próbuje odgadnąć typ na podstawie sygnatury (magic bytes) na początku pliku. JPEG zaczyna się od bajtów FF D8 FF, PNG — od 89 50 4E 47, a PDF — od 25 50 44 46. Ten proces jest potencjalnie niebezpieczny i wyłączany przez nagłówek X-Content-Type-Options: nosniff.

W aplikacjach mobilnych Content-Type jest obsługiwany przez klientów HTTP. OkHttp na Androidzie automatycznie analizuje nagłówek Content-Type z odpowiedzi i udostępnia go przez metodę Response.header("Content-Type"). Klient iOS URLSession robi to samo przez właściwość URLResponse.mimeType. Na obu platformach Content-Type jest używany do wyboru parsera: JSON — przez Moshi lub Gson na Androidzie, przez Codable na iOS; obrazy — przez Glide, Coil lub SDWebImage.

Content Negotiation przez Accept i Content-Type

Content negotiation (negocjowanie treści) — mechanizm HTTP, w którym klient określa żądany format odpowiedzi przez nagłówek Accept, a serwer wybiera odpowiedni format i zwraca go z odpowiednim Content-Type. Na przykład klient wysyła Accept: application/json, serwer odpowiada Content-Type: application/json. Jeśli serwer nie może dostarczyć żądanego formatu, zwraca 406 Not Acceptable. W REST API ten mechanizm pozwala jednemu endpointowi zwracać dane w JSON, XML lub HTML.

Content-Type w żądaniach i odpowiedziach

Nagłówek Content-Type jest używany zarówno w żądaniach HTTP (Request), jak i odpowiedziach HTTP (Response). W żądaniach określa format treści żądania, na przykład przy wysyłaniu JSON przez POST. W odpowiedziach — format zwracanych danych. Zasadnicza różnica polega na tym, że Content-Type żądania ustawia klient, a Content-Type odpowiedzi — serwer. Nieprawidłowe ustawienie Content-Type w żądaniu powoduje, że serwer nie może sparsować treści, zwracając błąd 400 Bad Request lub 415 Unsupported Media Type.

W żądaniach HTTP Content-Type jest obowiązkowy dla metod POST, PUT i PATCH, jeśli żądanie zawiera treść (body). GET, HEAD i DELETE zazwyczaj nie używają treści, więc Content-Type dla nich nie jest określany lub jest ignorowany. Przy wysyłaniu formularza HTML z atrybutem enctype="multipart/form-data" przeglądarka automatycznie ustawia Content-Type: multipart/form-data z unikalnym łańcuchem granicznym (boundary), który rozdziela części złożonego żądania. Każda część jest oddzielana przez --boundary, a koniec żądania oznaczany przez --boundary--.

W odpowiedziach HTTP Content-Type jest ustawiany przez serwer. Jeśli serwer nie określa Content-Type, klient albo włącza MIME sniffing, albo przetwarza odpowiedź jako application/octet-stream. Metoda HTTP HEAD pozwala uzyskać nagłówki odpowiedzi, w tym Content-Type, bez przesyłania treści. Jest to przydatne do sprawdzenia typu zasobu przed jej pełnym załadowaniem. Serwery CDN mogą nadpisywać Content-Type przy transformacji treści — na przykład przy konwersji obrazów do WebP.

kotlin
import okhttp3.*

fun checkContentType() {
    val client = OkHttpClient()
    val request = Request.Builder()
        .url("https://api.example.com/resource")
        .head()
        .build()

    client.newCall(request).execute().use { response ->
        val contentType = response.header("Content-Type")
        val mediaType = MediaType.parse(contentType)
        println("Rodzaj: ${mediaType?.type}, Podtyp: ${mediaType?.subtype}")
    }
}

Content-Type w mobilnych klientach HTTP

W programowaniu mobilnym nagłówek Content-Type jest obsługiwany automatycznie przez klientów HTTP. W OkHttp na Androidzie Content-Type jest ustawiany przez RequestBody: val body = "{}".toRequestBody("application/json".toMediaType()). Retrofit zarządza Content-Type przez adnotacje: @Body dla JSON, @Part dla multipart. Na iOS URLSession ustawia Content-Type dla HTTPBody, a Alamofire robi to przez parametr encoding: JSONEncoding.default lub URLEncoding.default. Ręczne ustawienie Content-Type jest wymagane przy pracy z surowymi gniazdami lub niestandardowymi protokołami.

Błędy przy pracy z Content-Type

Nieprawidłowy Content-Type — jeden z najczęstszych problemów przy tworzeniu i integracji usług internetowych. Najczęstszym błędem jest sytuacja, gdy serwer zwraca text/html zamiast application/json. Klient otrzymuje JSON jako ciąg HTML, nie może go sparsować i zgłasza wyjątek. Dzieje się tak, gdy framework webowy jest skonfigurowany domyślnie na HTML, a programista zapomina nadpisać Content-Type dla endpointu API. W PHP objawia się to brakiem header('Content-Type: application/json'), w Spring Boot — brakiem adnotacji produces.

Drugim co do częstotliwości błędem jest nieprawidłowy lub brakujący charset. Jeśli serwer wysyła text/html; charset=iso-8859-1, a przeglądarka oczekuje UTF-8, znaki cyrylicy wyświetlają się jako krzaki. Ten problem jest charakterystyczny dla starych stron, które nie przeszły na UTF-8. Dla JSON taki błąd występuje rzadziej, ponieważ RFC 8259 nakazuje UTF-8 bez dodatkowego uzgadniania. Rozwiązanie — zawsze jawnie określać charset=utf-8 dla tekstowych typów MIME w konfiguracji serwera.

Trzeci problem — niezgodność Content-Type z rzeczywistą zawartością. Jeśli serwer wysyła Content-Type: image/png, a treść odpowiedzi zawiera obraz WebP, przeglądarka może go nie dekodować. Serwery CDN czasami kompresują obrazy ze zmianą formatu, ale nie aktualizują nagłówka Content-Type. Sprawdzenie zgodności Content-Type z rzeczywistą zawartością — obowiązkowy etap testowania API i testów integracyjnych aplikacji mobilnych.

Diagnostyka i naprawa błędów Content-Type

Do debugowania używaj narzędzi deweloperskich przeglądarki (zakładka Network), curl z flagą -I do sprawdzania nagłówków odpowiedzi lub snifferów ruchu typu Charles Proxy i Wireshark. Nginx konfiguruje się przez dyrektywę include mime.types, Apache — przez AddType i AddDefaultCharset. Dla plików statycznych zawsze sprawdzaj, czy rozszerzenie pliku odpowiada jego typowi MIME. Dla odpowiedzi dynamicznych we wszystkich językach programowania jawnie ustawiaj Content-Type przed wypisaniem danych — zapobiega to zdecydowanej większości problemów.

Często zadawane pytania

Co się stanie, jeśli nie określę Content-Type w odpowiedzi HTTP?

Bez Content-Type przeglądarka włącza MIME sniffing — analizę pierwszych bajtów odpowiedzi w celu automatycznego określenia typu danych. Może to prowadzić do nieprawidłowego przetwarzania treści i tworzyć luki bezpieczeństwa. Nowoczesne przeglądarki z nagłówkiem X-Content-Type-Options: nosniff całkowicie blokują zgadywanie.

Czym różni się Content-Type od Accept w HTTP?

Content-Type określa format danych przesyłanych w bieżącej wiadomości (treści żądania lub odpowiedzi). Accept — to nagłówek żądania, który informuje serwer, jaki format odpowiedzi preferuje klient. Content-Type ustawia nadawca danych, a Accept — odbiorca, i uczestniczą one w mechanizmie negocjowania treści.

Jaki jest prawidłowy Content-Type dla JSON?

Oficjalny typ MIME dla JSON — application/json zgodnie ze specyfikacją RFC 8259. Wcześniej używany był text/x-json, ale ten typ jest przestarzały. Parametr charset dla application/json nie jest potrzebny, ponieważ JSON zgodnie ze specyfikacją jest zawsze przesyłany w kodowaniu UTF-8, UTF-16 lub UTF-32 z automatycznym wykrywaniem kolejności bajtów (BOM).

Dlaczego serwer zwraca text/html zamiast application/json?

Dzieje się tak, gdy framework webowy nie nadpisuje domyślnego Content-Type dla endpointów API. W PHP naprawia się to wywołaniem header('Content-Type: application/json'), w Spring Boot — adnotacją @GetMapping(produces = "application/json"), w Express.js — metodą res.set('Content-Type', 'application/json').

Co oznacza Content-Type: application/octet-stream?

application/octet-stream — uniwersalny typ MIME dla danych binarnych, których format jest nieznany. Przeglądarka nie próbuje wyświetlić takiego pliku w oknie, ale oferuje zapisanie go na dysku. Jest używany do pobierania plików, załączników e-mail i danych strumieniowych, gdy serwer nie może określić dokładnego typu przesyłanej treści.

Podsumowanie

  • Content-Type — nagłówek HTTP określający typ MIME przesyłanych danych, obowiązkowy dla wiadomości z treścią.
  • Typ MIME składa się z kategorii (text, image, application) i podtypu (html, json, png), rozdzielonych ukośnikiem — na przykład text/html lub application/json.
  • Parametr charset określa kodowanie dla typów tekstowych; standardem dla sieci jest UTF-8, jawne określenie zapobiega problemom z wyświetlaniem znaków.
  • Content-Type jest używany zarówno w żądaniach (POST, PUT), jak i odpowiedziach, wpływając na wybór parsera i przetwarzanie danych przez klienta.
  • Błędy Content-Type prowadzą do nieprawidłowego wyświetlania, problemów z parsowaniem, błędów 400/415 i luk MIME sniffing.
  • Nagłówek X-Content-Type-Options: nosniff wyłącza zgadywanie typu MIME przez przeglądarkę i jest zalecany przez OWASP dla wszystkich aplikacji webowych.
  • Sprawdzanie Content-Type w testach API jest obowiązkowe — każdy endpoint powinien zwracać oczekiwany typ MIME, odpowiadający rzeczywistej treści odpowiedzi.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również