Chunked Transfer — is een mechanisme van het HTTP-protocol waarbij de server de antwoordbody in afzonderlijke fragmenten (chunks) verzendt, zonder vooraf de totale gegevensgrootte aan te geven. Elke chunk bevat zijn eigen grootte in hexadecimaal formaat en gegevens van de aangegeven lengte, en eindigt met een laatste chunk van nul grootte. Volgens MDN Web Docs, 2025, wordt Transfer-Encoding: chunked automatisch ingeschakeld door de server wanneer de grootte van het antwoord niet van tevoren bekend is — bijvoorbeeld bij het genereren van inhoud ter plaatse of bij het streamen van gegevens.
Belangrijkste punten
Chunked Transfer is een HTTP-mechanisme gedefinieerd in de HTTP/1.1-specificatie (RFC 7230, sectie 4.1) waarmee de server de antwoordbody in delen kan verzenden zonder de totale Content-Length op te geven. In plaats van de antwoordgrootte vóór verzending te berekenen, begint de server onmiddellijk met de overdracht en verzendt gegevens in fragmenten zodra ze gereed zijn. Elk fragment gaat vergezeld van zijn eigen grootte-header, waardoor de client het antwoord uit stukjes kan assembleren.
Het mechanisme wordt ingeschakeld door de header Transfer-Encoding: chunked. Wanneer de client deze header in het antwoord ziet, weet hij dat de body in chunks wordt verzonden en moet hij het antwoord in een lus lezen: lees de chunk-grootte, lees vervolgens de gegevens van de opgegeven grootte, en herhaal. Het proces eindigt wanneer een chunk van nul grootte wordt aangetroffen. Chunked Transfer is een verplicht onderdeel van HTTP/1.1 en wordt ondersteund door alle moderne webservers en HTTP-cliënten.
De belangrijkste reden voor het gebruik van chunked transfer is dynamische inhoudsgeneratie. Wanneer de server een antwoord genereert op basis van een databasequery, externe API of langdurige berekening, kan hij de grootte van het resultaat niet van tevoren weten. In plaats van het volledige antwoord in het geheugen te bufferen (wat riskant is voor grote volumes), schakelt de server Transfer-Encoding: chunked in en verzendt gegevens zodra ze gereed zijn. Dit is vooral belangrijk voor servers met beperkt geheugen en voor antwoorden waarvan de grootte zeer groot kan zijn — vanaf 100 MB en meer.
In HTTP/2 bestaat het chunked transfer-mechanisme als zodanig niet, omdat het protocol multiplexing van stromen op frameniveau gebruikt. In HTTP/2 worden gegevens van elke grootte verzonden in DATA-frames en hoeft de grootte van de antwoordbody niet vooraf te worden gedeclareerd — de stroom kan op elk moment worden gesloten. Moderne servers converteren HTTP/1.1 chunked-antwoorden automatisch naar equivalente stromende overdracht bij proxy naar een HTTP/2 upstream. Chunked Transfer blijft relevant voor HTTP/1.1-verbindingen.
Wanneer de server besluit Chunked Transfer te gebruiken, berekent hij geen Content-Length, maar verzendt de header Transfer-Encoding: chunked. Vervolgens wordt de antwoordbody gevormd als een reeks chunks. Elke chunk begint met een regel die de chunk-grootte in hexadecimaal formaat bevat (zonder het voorvoegsel 0x), gevolgd door CRLF ( ). Daarna komen de chunk-gegevens van de opgegeven grootte, afgesloten met CRLF. De laatste chunk heeft grootte 0, waarna trailer-headers kunnen volgen.
De hexadecimale grootte maakt het mogelijk chunks van elke grootte te verzenden — van 1 byte tot theoretisch onbeperkt volume. In de praktijk wordt de chunk-grootte door de server gekozen: typische waarden zijn 4 KB, 8 KB of 16 KB. De optimale chunk-grootte is een veelvoud van de TCP-segmentgrootte (meestal 1460 bytes voor Ethernet) om fragmentatie op transportniveau te minimaliseren. Nginx gebruikt standaard chunks van 4 KB, Apache — van 8 KB.
De client die Transfer-Encoding: chunked heeft ontvangen, is verplicht het antwoord chunk voor chunk te lezen tot de laatste nul-chunk. Als de client chunked transfer niet ondersteunt, kan de server deze modus niet gebruiken. In de praktijk ondersteunen alle moderne HTTP-cliënten — browsers, OkHttp, URLSession, curl — chunked-antwoorden volledig. Het streamen van het lezen stelt de client in staat te beginnen met het verwerken van gegevens voordat het volledige antwoord is ontvangen, wat cruciaal is voor de prestaties.
| Chunk-element | Formaat | Voorbeeld |
|---|---|---|
| Chunk-grootte | HEX + CRLF | 1000 |
| Chunk-gegevens | [grootte bytes] + CRLF | [4096 bytes gegevens] |
| Afsluitende chunk | 0 | 0 |
| Trailer (optioneel) | Headers + CRLF | Expires: Wed, 21 Oct 2025 |
Chunked Transfer ondersteunt trailer-headers — extra HTTP-headers die na de laatste chunk worden verzonden. Dit is handig voor metadata die pas bekend wordt na voltooiing van de antwoordgeneratie: bijvoorbeeld Content-MD5 of X-Compression-Ratio. Trailer-headers moeten worden gedeclareerd in de Trailer-header: Content-MD5, X-Compression-Ratio. In de praktijk worden trailers zelden gebruikt — de meeste servers voegen ze niet toe aan antwoorden.
Een chunked antwoord heeft een strikt gedefinieerde structuur die de client correct moet parseren. Laten we een volledig voorbeeld bekijken van een HTTP-antwoord met Transfer-Encoding: chunked. Na de headers en de lege regel begint de antwoordbody. De lichaamsstructuur is een reeks: chunk_grootte gegevens chunk_grootte gegevens ... tot 0 . Elke grootte wordt verzonden in het hexadecimale getalsysteem met ASCII-tekens.
Voorbeeld van een serverantwoord met Chunked Transfer:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
7
Hello
6
World!
0
In dit voorbeeld verzendt de server de string „Hello World!” in twee chunks. De eerste chunk van 7 bytes bevat „Hello ”, de tweede — 6 bytes „World!”. De client verzamelt gegevens uit beide chunks en krijgt de volledige string. Belangrijk: de chunk-grootte omvat alleen de gegevens, niet de CRLF-scheidingstekens van de chunks zelf. De laatste lege chunk (0 ) informeert de client over het einde van de verzending.
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 abstraheert de programmeur volledig van de details van Chunked Transfer. Bij ontvangst van een antwoord met Transfer-Encoding: chunked verzamelt OkHttp automatisch de chunks en biedt de programmeur de volledige antwoordbody via response.body?.string(). Voor streaming verwerking wordt response.body?.source() gebruikt, die een BufferedSource retourneert en het mogelijk maakt gegevens te lezen zodra ze binnenkomen. De programmeur hoeft niet handmatig hex-groottes en CRLF te parseren — de bibliotheek doet dit automatisch.
Content-Length en Transfer-Encoding: chunked zijn twee elkaar uitsluitende manieren om de grootte van de HTTP-berichtbody aan te geven. Content-Length is een header die de exacte lichaamsgrootte in bytes bevat. Het is verplicht voor antwoorden waarvan de grootte van tevoren bekend is en voor verzoeken met een body (POST, PUT). Content-Length stelt de client in staat vooraf een buffer van de juiste grootte toe te wijzen en te controleren of alle gegevens zijn ontvangen.
Chunked Transfer wordt gebruikt wanneer de lichaamsgrootte niet van tevoren bekend is. Dit gebeurt in drie belangrijke scenario's: dynamische inhoudsgeneratie (bijvoorbeeld een databasequery waarvan het resultaat nog niet is ontvangen), het streamen van grote bestanden (om niet het hele bestand in het geheugen te bufferen) en Server-Sent Events (SSE) voor real-time gebeurtenisoverdracht. De keuze tussen Content-Length en chunked is de verantwoordelijkheid van de server. Als de server de grootte kent voordat de verzending begint, moet hij Content-Length gebruiken als een eenvoudiger en voorspelbaarder mechanisme.
De HTTP/1.1-specificatie verbiedt het gelijktijdig gebruik van Content-Length en Transfer-Encoding: chunked. Als de server beide headers verzendt, moet de client Content-Length negeren en het antwoord als chunked verwerken. De prioriteit van Transfer-Encoding boven Content-Length is vastgesteld in RFC 7230 voor gevallen waarin een proxyserver de antwoordbody wijzigt en de oorspronkelijke Content-Length niet kan behouden. Sommige oudere HTTP-cliënten verwerken deze situatie onjuist, maar moderne implementaties volgen de specificatie.
Er zijn scenario's waarin Content-Length principieel niet van tevoren kan worden berekend. Dynamische rapporten gegenereerd op verzoek van de gebruiker met filtering en aggregatie — de server kent het gegevensvolume pas na voltooiing van de databasequery. Streaming video verzonden vanaf een camera in real-time — de grootte is oneindig. SSE en long polling voor meldingen — het antwoord kan onbepaald lang duren. In al deze gevallen is Chunked Transfer het enige correcte mechanisme.
Chunked Transfer vormt de basis van veel streaming-technologieën op het web. De bekendste is Server-Sent Events (SSE), waarbij de server gebeurtenissen naar de client stuurt via een enkele HTTP-verbinding met Transfer-Encoding: chunked. SSE gebruikt een speciaal tekstformaat (data: bericht ), maar de transportlaag is gewone chunked transfer. De browser ontvangt gebeurtenissen zodra ze door de server worden verzonden, zonder te wachten op voltooiing van het antwoord.
Audio- en videostreaming is ook gebaseerd op Chunked Transfer. Mediaservers zoals Nginx RTMP en Wowza Streaming Engine verzenden mediagegevens in chunks via HTTP. De speler aan de clientzijde begint met afspelen zodra de eerste chunk is ontvangen, zonder te wachten tot het bestand volledig is geladen. Dit verkort de tijd tot het begin van het afspelen (Time to First Frame) van tientallen seconden tot 1-2 seconden. YouTube en Netflix gebruiken precies deze benadering voor hun HTTP-streams.
Bij de ontwikkeling van mobiele apps wordt Chunked Transfer gebruikt voor het verzenden van grote hoeveelheden gegevens zonder het volledige antwoord in het geheugen te laden. Bij het laden van afbeeldingen via Coil of Glide op Android lezen de bibliotheken streaming gegevens in chunks en decoderen de afbeelding geleidelijk. Dit maakt het mogelijk grote afbeeldingen (10+ MB) weer te geven zonder OutOfMemoryError. OkHttp ondersteunt streaming lezen via response.body?.byteStream(), die een InputStream retourneert die gegevens chunk voor chunk leest.
gRPC gebruikt HTTP/2, waarbij streaming overdracht op protocolniveau is ingebouwd en geen apart chunked-mechanisme vereist. GraphQL-servers die via HTTP/1.1 werken, kunnen Chunked Transfer gebruiken voor het streamen van abonnementsresultaten (subscriptions). Apollo Server en Hasura verzenden chunked-antwoorden voor GraphQL-abonnementen en geven gebeurtenissen door zodra ze zich voordoen. De client ontvangt real-time updates zonder polling.
Chunked Transfer biedt belangrijke voordelen voor webapplicaties. Onmiddellijke gegevensverzending — de server buffert het antwoord niet voor verzending, waardoor de latentie tot de eerste byte afneemt. Streaming verwerking — de client kan beginnen met het verwerken van gegevens zodra ze binnenkomen, zonder te wachten op volledig laden. Geen geheugenbeperkingen — de server slaat het volledige antwoord niet in het geheugen op, wat cruciaal is voor grote gegevensvolumes. Mogelijkheid tot het verzenden van oneindige streams — SSE, live video, monitoring.
Chunked Transfer heeft echter beperkingen. Overhead voor elke chunk bedraagt 6-12 bytes voor grootte + CRLF, wat voor een groot aantal kleine chunks (bijvoorbeeld 100 bytes) de antwoordgrootte met 10-15% kan verhogen. Onmogelijkheid om de exacte grootte aan te geven — de client kan niet vooraf een buffer toewijzen of een voortgangsbalk weergeven. Problemen met proxyservers — sommige oudere proxy's ondersteunen chunked transfer niet en kunnen dergelijke antwoorden niet cachen. Geen ondersteuning voor het hervatten van downloads — voor gedeeltelijk ontvangen chunked-antwoorden kan geen Range-verzoek worden gedaan.
Volgens HTTP Archive, 2025 gebruikt ongeveer 35% van alle HTTP-antwoorden Transfer-Encoding: chunked. Daaronder overheersen dynamische pagina's (60%), API-antwoorden (25%) en mediastreams (15%). Statische bestanden gebruiken bijna altijd Content-Length omdat hun grootte van tevoren bekend is. Het aandeel chunked-antwoorden neemt geleidelijk af met de verspreiding van HTTP/2, waarbij streaming overdracht op frameniveau wordt geïmplementeerd zonder dat een extra Transfer-Encoding-header nodig is.
Gebruik Chunked Transfer bij mobiele app-ontwikkeling voor het laden van grote bestanden (afbeeldingen, video) en voor API-verzoeken die grote gegevensarrays retourneren. OkHttp ondersteunt chunked transfer volledig zonder extra configuratie. Voor uploaden naar de server (upload) wordt Chunked Transfer niet toegepast — Transfer-Encoding wordt niet gebruikt voor upload in HTTP/1.1. Op iOS ondersteunt URLSession zowel het verzenden als ontvangen van chunked-gegevens zonder speciale configuratie. Het streamen van JSON-parsing (bijvoorbeeld via Jackson Streaming API of Moshi) maakt het mogelijk grote JSON-arrays te verwerken terwijl de chunked-stroom binnenkomt.
Veelgestelde vragen
De server schakelt Chunked Transfer automatisch in wanneer de antwoordgrootte onbekend is. Nginx voegt Transfer-Encoding: chunked toe als Content-Length niet is ingesteld. In Spring Boot gebruiken StreamingResponseBody en SseEmitter automatisch chunked transfer. In Node.js Express wordt het antwoord chunked als res.write() en res.end() worden aangeroepen zonder Content-Length.
Nee, de HTTP/1.1-specificatie verbiedt gelijktijdig gebruik van Content-Length en Transfer-Encoding: chunked. Als de server beide headers verzendt, moet de client Content-Length negeren en het antwoord als chunked verwerken. Deze regel is vastgesteld in RFC 7230 voor compatibiliteit met proxyservers die de antwoordbody kunnen wijzigen.
De optimale chunk-grootte hangt af van het scenario. Voor gewone webpagina's — 4-8 KB. Voor videostreaming — 16-64 KB. Voor SSE — minimale chunks van 1-2 KB om latentie te verminderen. De chunk-grootte moet een veelvoud zijn van de TCP-segmentgrootte (1460 bytes voor Ethernet) om fragmentatie op transportniveau te minimaliseren.
Moderne proxyservers (Nginx, HAProxy, Envoy) ondersteunen Chunked Transfer. De proxy kan chunks doorsturen zonder buffering (streaming) of het volledige antwoord bufferen en opnieuw verzenden met Content-Length. Oudere proxy's kunnen het chunked-antwoord bufferen tot voltooiing, wat de latentie verhoogt. HTTP/2 lost dit probleem op protocolniveau op.
Het is hetzelfde. Chunked Transfer is de volledige naam van het mechanisme uit de HTTP/1.1-specificatie. HTTP chunked encoding is hetzelfde, soms gebruikt in bibliotheekdocumentatie. Transfer-Encoding: chunked is de header die deze modus inschakelt. Alle drie termen beschrijven hetzelfde mechanisme voor het in delen verzenden van gegevens.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook