Chunked Transfer w tworzeniu stron internetowych — co to jest, format i zasada przesyłania chunkami

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

Chunked Transfer — to mechanizm protokołu HTTP, w którym serwer przesyła treść odpowiedzi w oddzielnych fragmentach (chunkach), nie podając z góry całkowitego rozmiaru danych. Każdy chunk zawiera swój rozmiar w formacie szesnastkowym i dane o określonej długości, a kończy się finalnym chunkiem o zerowym rozmiarze. Według MDN Web Docs, 2025, Transfer-Encoding: chunked jest włączany automatycznie przez serwer, gdy rozmiar odpowiedzi nie jest znany z góry — na przykład przy generowaniu treści na bieżąco lub strumieniowym przesyłaniu danych.

Najważniejsze

  • Chunked Transfer — przesyłanie odpowiedzi HTTP częściami bez wcześniejszego podawania Content-Length.
  • Transfer-Encoding: chunked — nagłówek włączający tryb przesyłania danych w chunkach.
  • Każdy chunk zawiera rozmiar w hex, dane i kończący CRLF, a koniec jest oznaczany chunkiem o zerowym rozmiarze.
  • Streaming — główne zastosowanie chunked transfer do przesyłania audio, wideo i zdarzeń SSE.
  • Chunked Transfer jest niekompatybilny z nagłówkiem Content-Length — nie są używane jednocześnie.

Co to jest Chunked Transfer?

Chunked Transfer — to mechanizm HTTP zdefiniowany w specyfikacji HTTP/1.1 (RFC 7230, sekcja 4.1), który pozwala serwerowi wysyłać treść odpowiedzi w częściach bez podawania całkowitego Content-Length. Zamiast obliczać rozmiar odpowiedzi przed wysłaniem, serwer rozpoczyna transmisję natychmiast, wysyłając dane fragmentami w miarę ich gotowości. Każdemu fragmentowi towarzyszy własny nagłówek rozmiaru, co pozwala klientowi składać odpowiedź z kawałków.

Mechanizm jest włączany nagłówkiem Transfer-Encoding: chunked. Gdy klient widzi ten nagłówek w odpowiedzi, wie, że treść będzie przesyłana w chunkach i powinien czytać odpowiedź w pętli: odczytać rozmiar chunka, następnie odczytać dane o podanym rozmiarze, a potem powtórzyć. Proces kończy się, gdy napotkany zostanie chunk o zerowym rozmiarze. Chunked Transfer to obowiązkowa część HTTP/1.1, obsługiwana przez wszystkie nowoczesne serwery WWW i klienty HTTP.

Głównym powodem używania chunked transfer jest dynamiczne generowanie treści. Gdy serwer generuje odpowiedź na podstawie zapytania do bazy danych, zewnętrznego API lub długotrwałych obliczeń, nie może z góry znać rozmiaru wyniku. Zamiast buforować całą odpowiedź w pamięci (co jest ryzykowne dla dużych objętości), serwer włącza Transfer-Encoding: chunked i wysyła dane w miarę ich gotowości. Jest to szczególnie ważne dla serwerów z ograniczoną pamięcią i dla odpowiedzi, których rozmiar może być bardzo duży — od 100 MB i więcej.

Różnica między HTTP/1.1 chunked a HTTP/2

W HTTP/2 mechanizm chunked transfer jako taki nie istnieje, ponieważ protokół używa multipleksowania strumieni na poziomie ramek. W HTTP/2 dane dowolnego rozmiaru są przesyłane w ramkach DATA, a rozmiar treści odpowiedzi nie musi być deklarowany z góry — strumień może zostać zamknięty w dowolnym momencie. Nowoczesne serwery automatycznie konwertują odpowiedzi chunked HTTP/1.1 na równoważną transmisję strumieniową podczas proxy na upstream HTTP/2. Chunked Transfer pozostaje aktualny dla połączeń HTTP/1.1.

Jak działa przesyłanie chunkami

Gdy serwer decyduje się użyć Chunked Transfer, nie oblicza Content-Length, ale wysyła nagłówek Transfer-Encoding: chunked. Następnie treść odpowiedzi jest tworzona jako sekwencja chunków. Każdy chunk rozpoczyna się od wiersza zawierającego rozmiar chunka w formacie szesnastkowym (bez prefiksu 0x), po którym następuje CRLF ( ). Następnie idą dane chunka o podanym rozmiarze, zakończone CRLF. Ostatni chunk ma rozmiar 0, po którym mogą nastąpić nagłówki trailer.

Szesnastkowy rozmiar pozwala przesyłać chunki dowolnego rozmiaru — od 1 bajtu do teoretycznie nieograniczonej objętości. W praktyce rozmiar chunka jest wybierany przez serwer: typowe wartości to 4 KB, 8 KB lub 16 KB. Optymalny rozmiar chunka jest wielokrotnością rozmiaru segmentu TCP (zwykle 1460 bajtów dla Ethernet), aby zminimalizować fragmentację na poziomie transportowym. Nginx domyślnie używa chunków po 4 KB, Apache — po 8 KB.

Klient, który otrzymał Transfer-Encoding: chunked, ma obowiązek czytać odpowiedź chunk po chunku aż do kończącego zerowego chunka. Jeśli klient nie obsługuje chunked transfer, serwer nie może użyć tego trybu. W praktyce wszystkie nowoczesne klienty HTTP — przeglądarki, OkHttp, URLSession, curl — w pełni obsługują odpowiedzi chunked. Strumieniowe odczytywanie pozwala klientowi rozpocząć przetwarzanie danych przed otrzymaniem pełnej odpowiedzi, co jest kluczowe dla wydajności.

Element chunkaFormatPrzykład
Rozmiar chunkaHEX + CRLF1000
Dane chunka[rozmiar bajtów] + CRLF[4096 bajtów danych]
Chunk kończący0 0
Trailer (opcjonalnie)Nagłówki + CRLFExpires: Wed, 21 Oct 2025

Nagłówki trailer w Chunked Transfer

Chunked Transfer obsługuje nagłówki trailer — dodatkowe nagłówki HTTP, które są przesyłane po ostatnim chunku. Jest to przydatne dla metadanych, które stają się znane dopiero po zakończeniu generowania odpowiedzi: na przykład Content-MD5 lub X-Compression-Ratio. Nagłówki trailer muszą być zadeklarowane w nagłówku Trailer: Content-MD5, X-Compression-Ratio. W praktyce trailer są rzadko używane — większość serwerów nie dołącza ich do odpowiedzi.

Format odpowiedzi chunked

Odpowiedź chunked ma ściśle określoną strukturę, którą klient musi poprawnie rozebrać. Rozważmy pełny przykład odpowiedzi HTTP z Transfer-Encoding: chunked. Po nagłówkach i pustym wierszu rozpoczyna się treść odpowiedzi. Struktura treści to sekwencja: rozmiar_chunka dane rozmiar_chunka dane ... aż do 0 . Każdy rozmiar jest przesyłany w systemie szesnastkowym za pomocą znaków ASCII.

Przykład odpowiedzi serwera z Chunked Transfer:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked

7
Hello
6
World!
0

W tym przykładzie serwer przesyła ciąg „Hello World!” dwoma chunkami. Pierwszy chunk o rozmiarze 7 bajtów zawiera „Hello ”, drugi — 6 bajtów „World!”. Klient zbiera dane z obu chunków i otrzymuje pełny ciąg. Ważne: rozmiar chunka obejmuje tylko dane, nie uwzględniając separatorów CRLF samych chunków. Kończący pusty chunk (0 ) informuje klienta o zakończeniu transmisji.

kotlin
import java.net.HttpURLConnection
import java.io.BufferedReader
import java.io.InputStreamReader

fun readChunkedResponse() {
    val url = java.net.URL("https://stream.example.com/data")
    val connection = url.openConnection() as HttpURLConnection
    val reader = BufferedReader(
        InputStreamReader(connection.inputStream)
    )

    var line: String?
    while (reader.readLine().also { line = it } != null) {
        println("Fragment: $line")
    }
    reader.close()
}

Parsowanie odpowiedzi chunked w OkHttp

OkHttp całkowicie abstrahuje programistę od szczegółów Chunked Transfer. Po otrzymaniu odpowiedzi z Transfer-Encoding: chunked, OkHttp automatycznie zbiera chunki i udostępnia programiście pełną treść odpowiedzi przez response.body?.string(). Do przetwarzania strumieniowego używa się response.body?.source(), który zwraca BufferedSource i pozwala czytać dane w miarę ich napływania. Programista nie musi ręcznie rozbierać rozmiarów hex i CRLF — biblioteka robi to automatycznie.

Chunked Transfer vs Content-Length

Content-Length i Transfer-Encoding: chunked to dwa wzajemnie wykluczające się sposoby określania rozmiaru treści wiadomości HTTP. Content-Length to nagłówek zawierający dokładny rozmiar treści w bajtach. Jest obowiązkowy dla odpowiedzi, których rozmiar jest znany z góry, oraz dla żądań z treścią (POST, PUT). Content-Length pozwala klientowi z góry przydzielić bufor o odpowiednim rozmiarze i sprawdzić, czy wszystkie dane zostały odebrane.

Chunked Transfer jest używany, gdy rozmiar treści nie jest znany z góry. Występuje to w trzech głównych scenariuszach: dynamiczne generowanie treści (na przykład zapytanie do bazy danych, którego wynik nie jest jeszcze znany), strumieniowe przesyłanie dużych plików (aby nie buforować całego pliku w pamięci) oraz Server-Sent Events (SSE) do przesyłania zdarzeń w czasie rzeczywistym. Wybór między Content-Length a chunked należy do serwera. Jeśli serwer zna rozmiar przed rozpoczęciem transmisji, powinien użyć Content-Length jako prostszego i bardziej przewidywalnego mechanizmu.

Specyfikacja HTTP/1.1 zabrania jednoczesnego używania Content-Length i Transfer-Encoding: chunked. Jeśli serwer wysyła oba nagłówki, klient musi zignorować Content-Length i przetwarzać odpowiedź jako chunked. Priorytet Transfer-Encoding nad Content-Length jest ustanowiony w RFC 7230 dla przypadków, gdy serwer proxy modyfikuje treść odpowiedzi i nie może zachować oryginalnego Content-Length. Niektóre stare klienty HTTP niepoprawnie obsługują tę sytuację, ale nowoczesne implementacje przestrzegają specyfikacji.

Kiedy Content-Length jest niemożliwy

Istnieją scenariusze, w których Content-Length zasadniczo nie może być obliczony z góry. Raporty dynamiczne generowane na żądanie użytkownika z filtrowaniem i agregacją — serwer nie zna objętości danych do czasu zakończenia zapytania do bazy. Strumieniowe wideo przesyłane z kamery w czasie rzeczywistym — rozmiar jest nieskończony. SSE i long polling dla powiadomień — odpowiedź może trwać nieokreślenie długo. We wszystkich tych przypadkach Chunked Transfer jest jedynym poprawnym mechanizmem.

Streaming oparty na chunked transfer

Chunked Transfer leży u podstaw wielu technologii strumieniowych w sieci. Najbardziej znaną jest Server-Sent Events (SSE), gdzie serwer wysyła zdarzenia do klienta przez jedno połączenie HTTP z Transfer-Encoding: chunked. SSE używa specjalnego formatu tekstowego (data: wiadomość ), ale warstwą transportową jest zwykły chunked transfer. Przeglądarka otrzymuje zdarzenia w miarę ich wysyłania przez serwer, nie czekając na zakończenie odpowiedzi.

Strumieniowanie audio i wideo również opiera się na Chunked Transfer. Serwery multimedialne, takie jak Nginx RTMP i Wowza Streaming Engine, wysyłają dane multimedialne w chunkach przez HTTP. Odtwarzacz po stronie klienta rozpoczyna odtwarzanie po otrzymaniu pierwszego chunka, nie czekając na pełne załadowanie pliku. Skraca to czas do rozpoczęcia odtwarzania (Time to First Frame) z kilkudziesięciu sekund do 1-2 sekund. YouTube i Netflix właśnie tego podejścia używają dla swoich strumieni HTTP.

W tworzeniu aplikacji mobilnych Chunked Transfer jest używany do przesyłania dużych ilości danych bez ładowania całej odpowiedzi do pamięci. Podczas ładowania obrazów przez Coil lub Glide na Androidzie biblioteki odczytują dane strumieniowo w chunkach i stopniowo dekodują obraz. Pozwala to wyświetlać duże obrazy (10+ MB) bez OutOfMemoryError. OkHttp obsługuje odczytywanie strumieniowe przez response.body?.byteStream(), który zwraca InputStream czytający dane chunk po chunku.

Chunked transfer w gRPC i GraphQL

gRPC używa HTTP/2, gdzie transmisja strumieniowa jest wbudowana na poziomie protokołu i nie wymaga oddzielnego mechanizmu chunked. Serwery GraphQL działające przez HTTP/1.1 mogą używać Chunked Transfer do strumieniowego przesyłania wyników subskrypcji (subscriptions). Apollo Server i Hasura wysyłają odpowiedzi chunked dla subskrypcji GraphQL, przesyłając zdarzenia w miarę ich występowania. Klient otrzymuje aktualizacje w czasie rzeczywistym bez konieczności pollingu.

Zalety i ograniczenia

Chunked Transfer zapewnia ważne korzyści dla aplikacji internetowych. Natychmiastowe wysyłanie danych — serwer nie buforuje odpowiedzi przed wysłaniem, zmniejszając opóźnienie (latency) do pierwszego bajtu. Przetwarzanie strumieniowe — klient może rozpocząć przetwarzanie danych w miarę ich napływania, nie czekając na pełne załadowanie. Brak ograniczeń pamięci — serwer nie przechowuje pełnej odpowiedzi w pamięci, co jest kluczowe dla dużych ilości danych. Możliwość przesyłania nieskończonych strumieni — SSE, wideo na żywo, monitoring.

Jednak Chunked Transfer ma ograniczenia. Narzut na każdy chunk wynosi 6-12 bajtów na rozmiar + CRLF, co dla dużej liczby małych chunków (na przykład po 100 bajtów) może zwiększyć rozmiar odpowiedzi o 10-15%. Niemożliwość podania dokładnego rozmiaru — klient nie może z góry przydzielić bufora ani pokazać paska postępu. Problemy z serwerami proxy — niektóre stare proxy nie obsługują chunked transfer i nie mogą buforować takich odpowiedzi. Brak obsługi wznawiania pobierania — dla częściowo odebranych odpowiedzi chunked nie można wykonać zapytania Range.

Według HTTP Archive, 2025, około 35% wszystkich odpowiedzi HTTP używa Transfer-Encoding: chunked. Wśród nich dominują strony dynamiczne (60%), odpowiedzi API (25%) i strumienie multimedialne (15%). Pliki statyczne prawie zawsze używają Content-Length, ponieważ ich rozmiar jest znany z góry. Udział odpowiedzi chunked stopniowo maleje wraz z rozpowszechnianiem się HTTP/2, gdzie transmisja strumieniowa jest zaimplementowana na poziomie ramek bez konieczności dodatkowego nagłówka Transfer-Encoding.

Praktyczne zalecenia

W tworzeniu aplikacji mobilnych używaj Chunked Transfer do pobierania dużych plików (obrazy, wideo) i dla zapytań API zwracających duże tablice danych. OkHttp w pełni obsługuje chunked transfer bez dodatkowej konfiguracji. W przypadku przesyłania na serwer (upload) Chunked Transfer nie jest stosowany — do tego służy Transfer-Encoding nie dla upload w HTTP/1.1. W iOS URLSession obsługuje zarówno wysyłanie, jak i odbieranie danych chunked bez specjalnej konfiguracji. Strumieniowe parsowanie JSON (na przykład przez Jackson Streaming API lub Moshi) pozwala przetwarzać duże tablice JSON w miarę napływania strumienia chunked.

Często zadawane pytania

Jak serwer włącza Chunked Transfer?

Serwer włącza Chunked Transfer automatycznie, gdy rozmiar odpowiedzi jest nieznany. Nginx dodaje Transfer-Encoding: chunked, jeśli nie ustawiono Content-Length. W Spring Boot StreamingResponseBody i SseEmitter automatycznie używają chunked transfer. W Node.js Express odpowiedź staje się chunked, jeśli wywoła się res.write() i res.end() bez Content-Length.

Czy można używać Content-Length i chunked jednocześnie?

Nie, specyfikacja HTTP/1.1 zabrania jednoczesnego używania Content-Length i Transfer-Encoding: chunked. Jeśli serwer wysyła oba nagłówki, klient musi zignorować Content-Length i przetwarzać odpowiedź jako chunked. Ta zasada jest ustanowiona w RFC 7230 dla zapewnienia zgodności z serwerami proxy, które mogą modyfikować treść odpowiedzi.

Jaki rozmiar chunka jest optymalny?

Optymalny rozmiar chunka zależy od scenariusza. Dla zwykłych stron internetowych — 4-8 KB. Dla strumieniowego przesyłania wideo — 16-64 KB. Dla SSE — minimalne chunki po 1-2 KB w celu zmniejszenia opóźnienia. Rozmiar chunka powinien być wielokrotnością rozmiaru segmentu TCP (1460 bajtów dla Ethernet) w celu minimalizacji fragmentacji na poziomie transportowym.

Czy Chunked Transfer działa przez proxy?

Nowoczesne serwery proxy (Nginx, HAProxy, Envoy) obsługują Chunked Transfer. Proxy może przekazywać chunki dalej bez buforowania (streaming) albo buforować całą odpowiedź i przesłać ją ponownie z Content-Length. Stare proxy mogą buforować odpowiedź chunked do zakończenia, co zwiększa opóźnienie. HTTP/2 rozwiązuje ten problem na poziomie protokołu.

Czym różni się Chunked Transfer od HTTP chunked encoding?

To jest to samo. Chunked Transfer to pełna nazwa mechanizmu ze specyfikacji HTTP/1.1. HTTP chunked encoding to to samo, czasami używane w dokumentacji bibliotek. Transfer-Encoding: chunked to nagłówek, który włącza ten tryb. Wszystkie trzy terminy opisują ten sam mechanizm przesyłania danych w częściach.

Podsumowanie

  • Chunked Transfer — mechanizm HTTP/1.1 przesyłający treść odpowiedzi w chunkach bez wcześniejszego podawania Content-Length.
  • Transfer-Encoding: chunked — nagłówek włączający transmisję chunkową; każdy chunk zawiera rozmiar hex, dane i CRLF.
  • Kończący chunk o zerowym rozmiarze sygnalizuje zakończenie transmisji, po nim mogą nastąpić nagłówki trailer.
  • Dynamic content streaming — główne zastosowanie: strony dynamiczne, SSE, strumieniowe audio/wideo, długie raporty.
  • Content-Length i chunked wzajemnie się wykluczają — specyfikacja zabrania jednoczesnego używania tych nagłówków.
  • Zalety — zmniejszenie opóźnienia, oszczędność pamięci, możliwość przesyłania nieskończonych strumieni i przetwarzanie strumieniowe po stronie klienta.
  • Ograniczenia — narzut na nagłówki chunków, niemożliwość pokazania postępu, problemy ze starymi serwerami proxy.

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ż