Chunked Transfer în dezvoltarea web — ce este, formatul și principiul transmiterii prin chunk-uri

Autor: IT Sectr Publicat: 2026-03-10 Timp de citire: 9 min

Chunked Transfer — este un mecanism al protocolului HTTP prin care serverul transmite corpul răspunsului în fragmente separate (chunk-uri), fără a indica dinainte dimensiunea totală a datelor. Fiecare chunk conține propria dimensiune în format hexazecimal și date de lungimea specificată, iar se încheie cu un chunk final de dimensiune zero. Potrivit MDN Web Docs, 2025, Transfer-Encoding: chunked este activat automat de server atunci când dimensiunea răspunsului nu este cunoscută dinainte — de exemplu, la generarea conținutului pe loc sau la transmiterea fluxurilor de date.

Principalele puncte

  • Chunked Transfer — transmiterea răspunsului HTTP în părți fără specificarea prealabilă a Content-Length.
  • Transfer-Encoding: chunked — antetul care activează modul de transmitere a datelor în chunk-uri.
  • Fiecare chunk conține dimensiunea în hex, datele și CRLF final, iar sfârșitul este marcat de un chunk de dimensiune zero.
  • Streaming — aplicația principală a chunked transfer pentru transmiterea audio, video și evenimentelor SSE.
  • Chunked Transfer este incompatibil cu antetul Content-Length — nu se utilizează simultan.

Ce este Chunked Transfer?

Chunked Transfer este un mecanism HTTP definit în specificația HTTP/1.1 (RFC 7230, secțiunea 4.1) care permite serverului să trimită corpul răspunsului în părți fără a indica Content-Length total. În loc să calculeze dimensiunea răspunsului înainte de trimitere, serverul începe transmisia imediat, trimițând datele în fragmente pe măsură ce sunt gata. Fiecare fragment este însoțit de propriul antet de dimensiune, permițând clientului să assembleze răspunsul din bucăți.

Mecanismul este activat de antetul Transfer-Encoding: chunked. Când clientul vede acest antet în răspuns, știe că corpul va fi transmis în chunk-uri și trebuie să citească răspunsul într-o buclă: să citească dimensiunea chunk-ului, apoi datele de dimensiunea specificată, apoi să repete. Procesul se încheie când este întâlnit un chunk de dimensiune zero. Chunked Transfer este o parte obligatorie a HTTP/1.1, acceptată de toate serverele web moderne și clienții HTTP.

Principalul motiv pentru utilizarea chunked transfer este generarea dinamică a conținutului. Când serverul generează un răspuns pe baza unei interogări de bază de date, a unui API extern sau a unui calcul de durată, nu poate cunoaște dinainte dimensiunea rezultatului. În loc să buferizeze întregul răspuns în memorie (ceea ce este riscant pentru volume mari), serverul activează Transfer-Encoding: chunked și trimite datele pe măsură ce sunt gata. Acest lucru este deosebit de important pentru serverele cu memorie limitată și pentru răspunsurile a căror dimensiune poate fi foarte mare — de la 100 MB în sus.

Diferența dintre HTTP/1.1 chunked și HTTP/2

În HTTP/2, mecanismul chunked transfer ca atare nu există, deoarece protocolul utilizează multiplexarea fluxurilor la nivel de cadre. În HTTP/2, datele de orice dimensiune sunt transmise în cadre DATA, iar dimensiunea corpului răspunsului nu trebuie declarată dinainte — fluxul poate fi închis în orice moment. Serverele moderne convertesc automat răspunsurile chunked HTTP/1.1 în transmisia echivalentă prin flux atunci când fac proxy la un upstream HTTP/2. Chunked Transfer rămâne relevant pentru conexiunile HTTP/1.1.

Cum funcționează transmiterea prin chunk-uri

Când serverul decide să utilizeze Chunked Transfer, nu calculează Content-Length, ci trimite antetul Transfer-Encoding: chunked. Apoi corpul răspunsului este format ca o secvență de chunk-uri. Fiecare chunk începe cu un rând care conține dimensiunea chunk-ului în format hexazecimal (fără prefixul 0x), urmat de CRLF ( ). Apoi urmează datele chunk-ului de dimensiunea specificată, terminate cu CRLF. Ultimul chunk are dimensiunea 0, după care pot urma antete trailer.

Dimensiunea hexazecimală permite transmiterea chunk-urilor de orice dimensiune — de la 1 octet la un volum teoretic nelimitat. în practică, dimensiunea chunk-ului este aleasă de server: valorile tipice sunt 4 KB, 8 KB sau 16 KB. Dimensiunea optimă a chunk-ului este un multiplu al dimensiunii segmentului TCP (de obicei 1460 de octeți pentru Ethernet) pentru a minimiza fragmentarea la nivel de transport. Nginx utilizează chunk-uri de 4 KB implicit, Apache — de 8 KB.

Clientul care a primit Transfer-Encoding: chunked este obligat să citească răspunsul chunk cu chunk până la chunk-ul final de dimensiune zero. Dacă clientul nu acceptă chunked transfer, serverul nu poate utiliza acest mod. în practică, toți clienții HTTP moderni — browserele, OkHttp, URLSession, curl — acceptă pe deplin răspunsurile chunked. Citirea fluxului permite clientului să înceapă procesarea datelor înainte de a primi răspunsul complet, ceea ce este esențial pentru performanță.

Elementul chunk-uluiFormatExemplu
Dimensiunea chunk-uluiHEX + CRLF1000
Datele chunk-ului[dimensiune octeți] + CRLF[4096 octeți de date]
Chunk final0 0
Trailer (opțional)Antete + CRLFExpires: Wed, 21 Oct 2025

Antetele trailer în Chunked Transfer

Chunked Transfer acceptă antete trailer — antete HTTP suplimentare care sunt transmise după ultimul chunk. Acest lucru este util pentru metadatele care devin cunoscute doar după finalizarea generării răspunsului: de exemplu, Content-MD5 sau X-Compression-Ratio. Antetele trailer trebuie declarate în antetul Trailer: Content-MD5, X-Compression-Ratio. în practică, trailer-urile sunt rareori utilizate — majoritatea serverelor nu le includ în răspunsuri.

Formatul răspunsului chunked

Răspunsul chunked are o structură strict definită pe care clientul trebuie să o analizeze corect. Să examinăm un exemplu complet de răspuns HTTP cu Transfer-Encoding: chunked. După antete și linia goală, începe corpul răspunsului. Structura corpului este o secvență: dimensiune_chunk date dimensiune_chunk date ... până la 0 . Fiecare dimensiune este transmisă în sistemul hexazecimal cu caractere ASCII.

Exemplu de răspuns server cu Chunked Transfer:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked

7
Hello
6
World!
0

în acest exemplu, serverul transmite șirul „Hello World!” în două chunk-uri. Primul chunk de 7 octeți conține „Hello ”, al doilea — 6 octeți „World!”. Clientul colectează datele din ambele chunk-uri și obține șirul complet. Important: dimensiunea chunk-ului include doar datele, nu și separatoarele CRLF ale chunk-urilor în sine. Chunk-ul gol final (0 ) înștiințează clientul despre sfârșitul transmisiei.

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()
}

Analizarea răspunsului chunked în OkHttp

OkHttp abstrage complet programatorul de detaliile Chunked Transfer. La primirea unui răspuns cu Transfer-Encoding: chunked, OkHttp colectează automat chunk-urile și pune la dispoziția programatorului corpul complet al răspunsului prin response.body?.string(). Pentru procesarea fluxului se utilizează response.body?.source(), care returnează un BufferedSource și permite citirea datelor pe măsură ce sosesc. Programatorul nu trebuie să analizeze manual dimensiunile hex și CRLF — biblioteca o face automat.

Chunked Transfer vs Content-Length

Content-Length și Transfer-Encoding: chunked sunt două moduri care se exclud reciproc de a indica dimensiunea corpului unui mesaj HTTP. Content-Length este un antet care conține dimensiunea exactă a corpului în octeți. Este obligatoriu pentru răspunsurile a căror dimensiune este cunoscută dinainte și pentru cererile cu corp (POST, PUT). Content-Length permite clientului să aloce dinainte un buffer de dimensiunea potrivită și să verifice dacă toate datele au fost primite.

Chunked Transfer este utilizat atunci când dimensiunea corpului nu este cunoscută dinainte. Acest lucru apare în trei scenarii principale: generarea dinamică a conținutului (de exemplu, o interogare de bază de date al cărei rezultat nu a fost încă obținut), transmiterea fluxurilor de fișiere mari (pentru a nu buferiza întregul fișier în memorie) și Server-Sent Events (SSE) pentru transmiterea evenimentelor în timp real. Alegerea între Content-Length și chunked este responsabilitatea serverului. Dacă serverul cunoaște dimensiunea înainte de începerea transmisiei, ar trebui să utilizeze Content-Length ca mecanism mai simplu și mai previzibil.

Specificația HTTP/1.1 interzice utilizarea simultană a Content-Length și Transfer-Encoding: chunked. Dacă serverul trimite ambele antete, clientul trebuie să ignore Content-Length și să proceseze răspunsul ca chunked. Prioritatea Transfer-Encoding față de Content-Length este stabilită în RFC 7230 pentru cazurile în care un server proxy modifică corpul răspunsului și nu poate păstra Content-Length original. Unii clienți HTTP mai vechi nu gestionează corect această situație, dar implementările moderne respectă specificația.

Când Content-Length este imposibil

Există scenarii în care Content-Length nu poate fi calculat dinainte din principiu. Rapoartele dinamice generate la cererea utilizatorului cu filtrare și agregare — serverul nu cunoaște volumul datelor până la finalizarea interogării bazei de date. Video flux transmis de la o cameră în timp real — dimensiunea este infinită. SSE și long polling pentru notificări — răspunsul poate dura indefinit. în toate aceste cazuri, Chunked Transfer este singurul mecanism corect.

Streaming bazat pe chunked transfer

Chunked Transfer stă la baza multor tehnologii de flux pe web. Cea mai cunoscută este Server-Sent Events (SSE), unde serverul trimite evenimente clientului printr-o singură conexiune HTTP cu Transfer-Encoding: chunked. SSE utilizează un format text special (data: mesaj ), dar stratul de transport este chunked transfer obișnuit. Browserul primește evenimentele pe măsură ce sunt trimise de server, fără a aștepta finalizarea răspunsului.

Transmiterea fluxurilor audio și video se bazează, de asemenea, pe Chunked Transfer. Servere media precum Nginx RTMP și Wowza Streaming Engine trimit date media în chunk-uri prin HTTP. Playerul de pe partea clientului începe redarea când primul chunk este primit, fără a aștepta încărcarea completă a fișierului. Aceasta reduce timpul până la începerea redării (Time to First Frame) de la zeci de secunde la 1-2 secunde. YouTube și Netflix utilizează exact această abordare pentru fluxurile lor HTTP.

în dezvoltarea aplicațiilor mobile, Chunked Transfer este utilizat pentru transmiterea volumelor mari de date fără a încărca întregul răspuns în memorie. La încărcarea imaginilor prin Coil sau Glide pe Android, bibliotecile citesc datele fluxului în chunk-uri și decodifică imaginea treptat. Acest lucru permite afișarea imaginilor mari (10+ MB) fără OutOfMemoryError. OkHttp acceptă citirea fluxurilor prin response.body?.byteStream(), care returnează un InputStream ce citește datele chunk cu chunk.

Chunked transfer în gRPC și GraphQL

gRPC utilizează HTTP/2, unde transmiterea prin flux este încorporată la nivel de protocol și nu necesită un mecanism chunked separat. Servere GraphQL care funcționează prin HTTP/1.1 pot utiliza Chunked Transfer pentru transmiterea fluxurilor rezultatelor abonamentelor (subscriptions). Apollo Server și Hasura trimit răspunsuri chunked pentru abonamentele GraphQL, transmițând evenimentele pe măsură ce apar. Clientul primește actualizări în timp real fără a fi nevoie de polling.

Avantaje și limitări

Chunked Transfer oferă avantaje importante pentru aplicațiile web. Trimiterea imediată a datelor — serverul nu buferizează răspunsul înainte de trimitere, reducând latența (întârzierea) până la primul octet. Procesarea fluxului — clientul poate începe să proceseze datele pe măsură ce sosesc, fără a aștepta încărcarea completă. Fără limitări de memorie — serverul nu stochează întregul răspuns în memorie, ceea ce este esențial pentru volume mari de date. Posibilitatea transmiterii fluxurilor infinite — SSE, video live, monitorizare.

Cu toate acestea, Chunked Transfer are limitări. Supraîncărcarea pentru fiecare chunk este de 6-12 octeți pentru dimensiune + CRLF, ceea ce pentru un număr mare de chunk-uri mici (de exemplu, 100 de octeți) poate crește dimensiunea răspunsului cu 10-15%. Imposibilitatea de a indica dimensiunea exactă — clientul nu poate aloca dinainte un buffer sau arăta o bară de progres. Probleme cu serverele proxy — unele proxy-uri mai vechi nu acceptă chunked transfer și nu pot stoca în cache astfel de răspunsuri. Lipsa suportului pentru reluarea încărcării — pentru răspunsurile chunked primite parțial nu se poate face o cerere Range.

Potrivit HTTP Archive, 2025, aproximativ 35% din toate răspunsurile HTTP utilizează Transfer-Encoding: chunked. Dintre acestea, paginile dinamice (60%), răspunsurile API (25%) și fluxurile media (15%) sunt predominante. Fișierele statice utilizează aproape întotdeauna Content-Length, deoarece dimensiunea lor este cunoscută dinainte. Ponderea răspunsurilor chunked scade treptat odată cu răspândirea HTTP/2, unde transmiterea prin flux este implementată la nivel de cadre fără a fi nevoie de un antet suplimentar Transfer-Encoding.

Recomandări practice

în dezvoltarea aplicațiilor mobile, utilizați Chunked Transfer pentru încărcarea fișierelor mari (imagini, video) și pentru cererile API care returnează matrice mari de date. OkHttp acceptă pe deplin chunked transfer fără configurare suplimentară. Pentru încărcarea pe server (upload), Chunked Transfer nu se aplică — în HTTP/1.1 nu se utilizează Transfer-Encoding pentru upload. Pe iOS, URLSession acceptă atât trimiterea, cât și primirea datelor chunked fără configurare specială. Analizarea fluxurilor JSON (de exemplu, prin Jackson Streaming API sau Moshi) permite procesarea matricelor JSON mari pe măsură ce fluxul chunked sosește.

întrebări frecvente

Cum activează serverul Chunked Transfer?

Serverul activează Chunked Transfer automat atunci când dimensiunea răspunsului nu este cunoscută. Nginx adaugă Transfer-Encoding: chunked dacă nu este setat Content-Length. în Spring Boot, StreamingResponseBody și SseEmitter utilizează automat chunked transfer. în Node.js Express, răspunsul devine chunked dacă se apelează res.write() și res.end() fără Content-Length.

Pot fi utilizate Content-Length și chunked simultan?

Nu, specificația HTTP/1.1 interzice utilizarea simultană a Content-Length și Transfer-Encoding: chunked. Dacă serverul trimite ambele antete, clientul trebuie să ignore Content-Length și să proceseze răspunsul ca chunked. Această regulă este stabilită în RFC 7230 pentru compatibilitatea cu serverele proxy care pot modifica corpul răspunsului.

Care dimensiune a chunk-ului este optimă?

Dimensiunea optimă a chunk-ului depinde de scenariu. Pentru pagini web obișnuite — 4-8 KB. Pentru transmiterea fluxurilor video — 16-64 KB. Pentru SSE — chunk-uri minime de 1-2 KB pentru reducerea latenței. Dimensiunea chunk-ului ar trebui să fie un multiplu al dimensiunii segmentului TCP (1460 de octeți pentru Ethernet) pentru a minimiza fragmentarea la nivel de transport.

Funcționează Chunked Transfer prin proxy?

Servere proxy moderne (Nginx, HAProxy, Envoy) acceptă Chunked Transfer. Proxy-ul poate transmite chunk-urile mai departe fără buferizare (streaming) sau poate buferiza întregul răspuns și îl poate retrimite cu Content-Length. Proxy-urile mai vechi pot buferiza răspunsul chunked până la finalizare, ceea ce crește latența. HTTP/2 rezolvă această problemă la nivel de protocol.

Cu ce se deosebește Chunked Transfer de HTTP chunked encoding?

Este același lucru. Chunked Transfer este denumirea completă a mecanismului din specificația HTTP/1.1. HTTP chunked encoding este același lucru, uneori utilizat în documentația bibliotecilor. Transfer-Encoding: chunked este antetul care activează acest mod. Toți cei trei termeni descriu același mecanism de transmitere a datelor în părți.

Rezumat

  • Chunked Transfer — mecanism HTTP/1.1 care transmite corpul răspunsului în chunk-uri fără a indica dinainte Content-Length.
  • Transfer-Encoding: chunked — antetul care activează transmiterea în chunk-uri; fiecare chunk conține dimensiunea hex, datele și CRLF.
  • Chunkul final de dimensiune zero semnalează sfârșitul transmisiei, după care pot urma antete trailer.
  • Dynamic content streaming — aplicația principală: pagini dinamice, SSE, audio/video în flux, rapoarte lungi.
  • Content-Length și chunked se exclud reciproc — specificația interzice utilizarea simultană a acestor antete.
  • Avantaje — reducerea latenței, economie de memorie, posibilitatea transmiterii fluxurilor infinite și procesarea fluxurilor pe client.
  • Limitări — supraîncărcarea antetelor chunk, imposibilitatea afișării progresului, probleme cu serverele proxy mai vechi.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și