Chunked Transfer — je mechanismus protokolu HTTP, při kterém server přenáší tělo odpovědi v oddělených fragmentech (chuncích), aniž by předem udával celkovou velikost dat. Každý chunk obsahuje svou velikost v hexadecimálním formátu a data uvedené délky a končí závěrečným chunchem nulové velikosti. Podle MDN Web Docs, 2025 se Transfer-Encoding: chunked automaticky zapíná serverem, když velikost odpovědi není předem známa — například při generování obsahu za běhu nebo streamovém přenosu dat.
Hlavní body
Chunked Transfer je HTTP mechanismus definovaný ve specifikaci HTTP/1.1 (RFC 7230, část 4.1), který umožňuje serveru odesílat tělo odpovědi po částech bez uvedení celkového Content-Length. Místo výpočtu velikosti odpovědi před odesláním server okamžitě zahájí přenos a odesílá data ve fragmentech, jakmile jsou připravena. Každý fragment je doprovázen vlastní hlavičkou velikosti, což klientovi umožňuje sestavit odpověď z kousků.
Mechanismus se zapíná hlavičkou Transfer-Encoding: chunked. Když klient vidí tuto hlavičku v odpovědí, ví, že tělo bude přenášeno v chuncích a musí číst odpověď ve smyčce: přečíst velikost chunku, poté data uvedené velikosti, poté opakovat. Proces končí, když je nalezen chunk nulové velikosti. Chunked Transfer je povinnou součástí HTTP/1.1, podporovanou všemi moderními webovými servery a HTTP klienty.
Hlavním důvodem pro použití chunked transfer je dynamické generování obsahu. Když server generuje odpověď na základě databázového dotazu, externího API nebo dlouhého výpočtu, nemůže předem znát velikost výsledku. Místo ukládání celé odpovědi do vyrovnávací paměti (což je riskantní pro velké objemy) server zapne Transfer-Encoding: chunked a odesílá data, jakmile jsou připravena. To je obzvláště důležité pro servery s omezenou pamětí a pro odpovědi, jejichž velikost může být velmi velká — od 100 MB výše.
V HTTP/2 mechanismus chunked transfer jako takový neexistuje, protože protokol používá multiplexování toků na úrovni rámců. V HTTP/2 se data libovolné velikosti přenášejí v rámccích DATA a velikost těla odpovědi nemusí být předem deklarována — tok lze kdykoli uzavřít. Moderní servery automaticky převádějí chunked odpovědi HTTP/1.1 na ekvivalentní streamový přenos při proxy na HTTP/2 upstream. Chunked Transfer zůstává relevantní pro připojení HTTP/1.1.
Když se server rozhodne použít Chunked Transfer, nevypočítává Content-Length, ale odesílá hlavičku Transfer-Encoding: chunked. Poté se tělo odpovědi vytvoří jako sekvence chunků. Každý chunk začíná řádkem obsahujícím velikost chunku v hexadecimálním formátu (bez předpony 0x), následovaným CRLF ( ). Poté následují data chunku uvedené velikosti, zakončená CRLF. Poslední chunk má velikost 0, po kterém mohou následovat trailer hlavičky.
Hexadecimální velikost umožňuje přenos chunků libovolné velikosti — od 1 bajtu po teoreticky neomezený objem. V praxi se velikost chunku volí serverem: typické hodnoty jsou 4 KB, 8 KB nebo 16 KB. Optimální velikost chunku je násobkem velikosti TCP segmentu (obvykle 1460 bajtů pro Ethernet), aby se minimalizovala fragmentace na transportní úrovni. Nginx standardně používá chunky o velikosti 4 KB, Apache — 8 KB.
Klient, který obdržel Transfer-Encoding: chunked, je povinen číst odpověď chunk po chunku až do závěrečného nulového chunku. Pokud klient chunked transfer nepodporuje, server nemůže tento režim použít. V praxi všichni moderní HTTP klienti — prohlížeče, OkHttp, URLSession, curl — plně podporují chunked odpovědi. Streamové čtení umožňuje klientovi zahájit zpracování dat ještě před přijetím úplné odpovědi, což je kritické pro výkon.
| Prvek chunku | Formát | Příklad |
|---|---|---|
| Velikost chunku | HEX + CRLF | 1000 |
| Data chunku | [velikost bajtů] + CRLF | [4096 bajtů dat] |
| Závěrečný chunk | 0 | 0 |
| Trailer (volitelný) | Hlavičky + CRLF | Expires: Wed, 21 Oct 2025 |
Chunked Transfer podporuje trailer hlavičky — další HTTP hlavičky, které se přenášejí po posledním chunku. To je užitečné pro metadata, která jsou známa až po dokončení generování odpovědi: například Content-MD5 nebo X-Compression-Ratio. Trailer hlavičky musí být deklarovány v hlavičce Trailer: Content-MD5, X-Compression-Ratio. V praxi se trailery používají zřídka — většina serverů je do odpovědí nezahrnuje.
Chunked odpověď má přísně definovanou strukturu, kterou musí klient správně解析ovat (parsovat). Podívejme se na úplný příklad HTTP odpovědi s Transfer-Encoding: chunked. Po hlavičkách a prázdném řádku začíná tělo odpovědi. Struktura těla je sekvence: velikost_chunku data velikost_chunku data ... až do 0 . Každá velikost se přenáší v hexadecimální číselné soustavě pomocí ASCII znaků.
Příklad odpovědi serveru s Chunked Transfer:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
7
Hello
6
World!
0
V tomto příkladě server přenáší řetězec „Hello World!” ve dvou chuncích. První chunk o velikosti 7 bajtů obsahuje „Hello ”, druhý — 6 bajtů „World!”. Klient shromáždí data z obou chunků a získá úplný řetězec. Důležité: velikost chunku zahrnuje pouze data, nikoli oddělovače CRLF samotných chunků. Závěrečný prázdný chunk (0 ) informuje klienta o konci přenosu.
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("Chunk: $line")
}
reader.close()
}
OkHttp zcela abstrahuje programátora od detailů Chunked Transfer. Při přijetí odpovědi s Transfer-Encoding: chunked OkHttp automaticky shromáždí chunky a poskytne programátorovi úplné tělo odpovědi prostřednictvím response.body?.string(). Pro streamové zpracování se používá response.body?.source(), který vrací BufferedSource a umožňuje čtení dat v průběhu jejich přijímání. Programátor nemusí ručně解析ovat hex velikosti a CRLF — knihovna to dělá automaticky.
Content-Length a Transfer-Encoding: chunked jsou dva vzájemně se vylučující způsoby, jak určit velikost těla HTTP zprávy. Content-Length je hlavička obsahující přesnou velikost těla v bajtech. Je povinná pro odpovědi, jejichž velikost je předem známa, a pro požadavky s tělem (POST, PUT). Content-Length umožňuje klientovi předem alokovat buffer správné velikosti a zkontrolovat, zda byla přijata všechna data.
Chunked Transfer se používá, když velikost těla není předem známa. K tomu dochází ve třech hlavních scénářích: dynamické generování obsahu (například databázový dotaz, jehož výsledek ještě nebyl obdržen), streamový přenos velkých souborů (aby nebyl celý soubor ukládán do vyrovnávací paměti) a Server-Sent Events (SSE) pro přenos událostí v reálném čase. Volba mezi Content-Length a chunked je odpovědností serveru. Pokud server zná velikost před zahájením přenosu, měl by použít Content-Length jako jednodušší a předvídatelnější mechanismus.
Specifikace HTTP/1.1 zakazuje současné použití Content-Length a Transfer-Encoding: chunked. Pokud server odešle obě hlavičky, klient musí ignorovat Content-Length a zpracovat odpověď jako chunked. Priorita Transfer-Encoding nad Content-Length je stanovena v RFC 7230 pro případy, kdy proxy server mění tělo odpovědi a nemůže zachovat původní Content-Length. Někteří starší HTTP klienti tuto situaci zpracovávají nesprávně, ale moderní implementace se řídí specifikací.
Existují scénáře, ve kterých Content-Length principiálně nelze předem vypočítat. Dynamické zprávy generované na základě uživatelského požadavku s filtrováním a agregací — server nezná objem dat do dokončení databázového dotazu. Streamové video přenášené z kamery v reálném čase — velikost je nekonečná. SSE a long polling pro oznámení — odpověď může trvat neurčitě dlouho. Ve všech těchto případech je Chunked Transfer jediným správným mechanismem.
Chunked Transfer je základem mnoha streamovacích technologií na webu. Nejznámější jsou Server-Sent Events (SSE), kde server odesílá události klientovi prostřednictvím jednoho HTTP připojení s Transfer-Encoding: chunked. SSE používá speciální textový formát (data: zpráva ), ale transportní vrstva je běžný chunked transfer. Prohlížeč přijímá události v okamžiku jejich odeslání serverem, aniž by čekal na dokončení odpovědi.
Streaming audia a videa se také spoléhá na Chunked Transfer. Mediální servery jako Nginx RTMP a Wowza Streaming Engine odesílají mediální data v chuncích prostřednictvím HTTP. Přehrávač na straně klienta začne přehrávat po přijetí prvního chunku, aniž by čekal na úplné načtení souboru. Tím se zkracuje doba do zahájení přehrávání (Time to First Frame) z desítek sekund na 1-2 sekundy. YouTube a Netflix používají přesně tento přístup pro své HTTP streamy.
Při vývoji mobilních aplikací se Chunked Transfer používá pro přenos velkých objemů dat bez načítání celé odpovědi do paměti. Při načítání obrázků prostřednictvím Coil nebo Glide na Androidu knihovny čtou streamovaná data v chuncích a postupně dekódují obrázek. To umožňuje zobrazovat velké obrázky (10+ MB) bez OutOfMemoryError. OkHttp podporuje streamové čtení prostřednictvím response.body?.byteStream(), který vrací InputStream čtoucí data chunk po chunku.
gRPC používá HTTP/2, kde je streamový přenos integrován na úrovni protokolu a nevyžaduje samostatný chunked mechanismus. GraphQL servery pracující přes HTTP/1.1 mohou používat Chunked Transfer pro streamový přenos výsledků odběrů (subscriptions). Apollo Server a Hasura odesílají chunked odpovědi pro GraphQL odběry a přenášejí události v okamžiku jejich vzniku. Klient dostává aktualizace v reálném čase bez nutnosti pollingu.
Chunked Transfer poskytuje důležité výhody pro webové aplikace. Okamžité odesílání dat — server neukládá odpověď do vyrovnávací paměti před odesláním, čímž se snižuje latence k prvnímu bajtu. Streamové zpracování — klient může začít zpracovávat data v průběhu jejich přijímání, aniž by čekal na úplné načtení. Žádná omezení paměti — server neuchovává celou odpověď v paměti, což je kritické pro velké objemy dat. Možnost přenosu nekonečných toků — SSE, živé video, monitorování.
Chunked Transfer má však omezení. Režie pro každý chunk činí 6-12 bajtů pro velikost + CRLF, což u velkého množství malých chunků (například 100 bajtů) může zvýšit velikost odpovědi o 10-15%. Nemožnost uvést přesnou velikost — klient nemůže předem alokovat buffer nebo zobrazit ukazatel průběhu. Problémy s proxy servery — některé starší proxy nepodporují chunked transfer a nemohou takové odpovědi ukládat do mezipaměti. Chybějící podpora obnovení stahování — pro částečně přijaté chunked odpovědi nelze provést požadavek Range.
Podle HTTP Archive, 2025 přibližně 35% všech HTTP odpovědí používá Transfer-Encoding: chunked. Mezi nimi převládají dynamické stránky (60%), API odpovědi (25%) a mediální streamy (15%). Statické soubory téměř vždy používají Content-Length, protože jejich velikost je předem známa. Podíl chunked odpovědí postupně klesá s rozšířením HTTP/2, kde je streamový přenos implementován na úrovni rámců bez potřeby další hlavičky Transfer-Encoding.
Při vývoji mobilních aplikací používejte Chunked Transfer pro načítání velkých souborů (obrázky, video) a pro API požadavky, které vracejí velké pole dat. OkHttp plně podporuje chunked transfer bez další konfigurace. Pro nahrávání na server (upload) se Chunked Transfer nepoužívá — Transfer-Encoding se pro upload v HTTP/1.1 nepoužívá. Na iOS URLSession podporuje odesílání i přijímání chunked dat bez speciální konfigurace. Streamová analýza JSON (například pomocí Jackson Streaming API nebo Moshi) umožňuje zpracovávání velkých JSON polí během přijímání chunked toku.
Často kladené otázky
Server zapíná Chunked Transfer automaticky, když velikost odpovědi není známa. Nginx přidá Transfer-Encoding: chunked, pokud není nastaven Content-Length. V Spring Boot StreamingResponseBody a SseEmitter automaticky používají chunked transfer. V Node.js Express se odpověď stane chunked, pokud se zavolá res.write() a res.end() bez Content-Length.
Ne, specifikace HTTP/1.1 zakazuje současné použití Content-Length a Transfer-Encoding: chunked. Pokud server odešle obě hlavičky, klient musí ignorovat Content-Length a zpracovat odpověď jako chunked. Toto pravidlo je stanoveno v RFC 7230 pro kompatibilitu s proxy servery, které mohou měnit tělo odpovědi.
Optimální velikost chunku závisí na scénáři. Pro běžné webové stránky — 4-8 KB. Pro streamový přenos videa — 16-64 KB. Pro SSE — minimální chunky o velikosti 1-2 KB pro snížení latence. Velikost chunku by měla být násobkem velikosti TCP segmentu (1460 bajtů pro Ethernet) pro minimalizaci fragmentace na transportní úrovni.
Moderní proxy servery (Nginx, HAProxy, Envoy) podporují Chunked Transfer. Proxy může předávat chunky dál bez ukládání do vyrovnávací paměti (streaming) nebo uložit celou odpověď do vyrovnávací paměti a znovu ji odeslat s Content-Length. Starší proxy mohou ukládat chunked odpověď do vyrovnávací paměti až do dokončení, což zvyšuje latenci. HTTP/2 řeší tento problém na úrovni protokolu.
Je to to samé. Chunked Transfer je úplný název mechanismu ze specifikace HTTP/1.1. HTTP chunked encoding je totéž, někdy používané v dokumentaci knihoven. Transfer-Encoding: chunked je hlavička, která zapíná tento režim. Všechny tři termíny popisují stejný mechanismus přenosu dat po částech.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také