Chunked Transfer ve vývoji webu — co to je, formát a princip přenosu po chuncích

Autor: IT Sectr Publikováno: 2026-03-10 Doba čtení: 9 min

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 — přenos HTTP odpovědi po částech bez předchozího uvedení Content-Length.
  • Transfer-Encoding: chunked — hlavička zapínající režim chunkového přenosu dat.
  • Každý chunk obsahuje velikost v hex, data a závěrečný CRLF, konec je označen chunchem nulové velikosti.
  • Streaming — hlavní použití chunked transfer pro přenos audia, videa a událostí SSE.
  • Chunked Transfer je nekompatibilní s hlavičkou Content-Length — nepoužívají se současně.

Co je Chunked Transfer?

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.

Rozdíl mezi HTTP/1.1 chunked a HTTP/2

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.

Jak funguje přenos po chuncích

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 chunkuFormátPříklad
Velikost chunkuHEX + CRLF1000
Data chunku[velikost bajtů] + CRLF[4096 bajtů dat]
Závěrečný chunk0 0
Trailer (volitelný)Hlavičky + CRLFExpires: Wed, 21 Oct 2025

Trailer hlavičky v Chunked Transfer

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.

Formát chunked odpovědi

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.

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("Chunk: $line")
    }
    reader.close()
}

Analýza chunked odpovědi v OkHttp

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.

Chunked Transfer vs Content-Length

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í.

Když Content-Length není možný

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.

Streaming založený na chunked transfer

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.

Chunked transfer v gRPC a GraphQL

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.

Výhody a omezení

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.

Praktické doporučení

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

Jak server zapíná Chunked Transfer?

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.

Lze používat Content-Length a chunked současně?

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.

Jaká velikost chunku je optimální?

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.

Funguje Chunked Transfer přes proxy?

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.

Čím se liší Chunked Transfer od HTTP chunked encoding?

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í

  • Chunked Transfer — mechanismus HTTP/1.1, který přenáší tělo odpovědi v chuncích bez předchozího uvedení Content-Length.
  • Transfer-Encoding: chunked — hlavička zapínající chunkový přenos; každý chunk obsahuje hex velikost, data a CRLF.
  • Závěrečný chunk nulové velikosti signalizuje konec přenosu, po kterém mohou následovat trailer hlavičky.
  • Dynamic content streaming — hlavní použití: dynamické stránky, SSE, streamové audio/video, dlouhé zprávy.
  • Content-Length a chunked se vzájemně vylučují — specifikace zakazuje současné použití těchto hlaviček.
  • Výhody — snížení latence, úspory paměti, možnost přenosu nekonečných toků a streamové zpracování na straně klienta.
  • Omezení — režie hlaviček chunků, nemožnost zobrazení průběhu, problémy se staršími proxy servery.

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í.

Prodiskutovat projekt

Přečtěte si také