Chunked Transfer у веб развоју — шта је то, формат и принцип преноса у чанковима

Аутор: IT Sectr Објављено: 2026-03-10 Време читања: 9 мин

Chunked Transfer — то је механизам HTTP протокола при којем сервер преноси тело одговора у одвојеним фрагментима (чанковима), без навођења унапред укупне величине података. Сваки чанк садржи своју величину у хексадецималном формату и податке наведене дужине, а завршава се финалним чанком нулте величине. Према MDN Web Docs, 2025, Transfer-Encoding: chunked се укључује аутоматски од стране сервера када величина одговора није унапред позната — на пример, при генерисању садржаја у лету или streaming преносу података.

Главно

  • Chunked Transfer — пренос HTTP одговора у деловима без претходног навођења Content-Length.
  • Transfer-Encoding: chunked — заглавље које укључује режим chunked преноса података.
  • Сваки чанк садржи величину у hex, податке и завршни CRLF, а крај се означава чанком нулте величине.
  • Streaming — основна примена chunked transfer за пренос аудио, видео и SSE догађаја.
  • Chunked Transfer је некомпатибилан са заглављем Content-Length — истовремено се не користе.

Шта је Chunked Transfer?

Chunked Transfer је HTTP механизам дефинисан у спецификацији HTTP/1.1 (RFC 7230, одељак 4.1) који омогућава серверу да шаље тело одговора у деловима без навођења укупног Content-Length. Уместо да израчуна величину одговора пре слања, сервер одмах почиње пренос, шаљући податке у фрагментима како су спремни. Сваки фрагмент је праћен сопственим заглављем величине, што омогућава клијенту да састави одговор из делова.

Механизам се укључује заглављем Transfer-Encoding: chunked. Када клијент види ово заглавље у одговору, зна да ће се тело преносити у чанковима и мора да чита одговор у петљи: прочита величину чанка, затим податке наведене величине, затим понови. Процес се завршава када се наиђе на чанк нулте величине. Chunked Transfer је обавезан део HTTP/1.1, подржан од свих модерних веб сервера и HTTP клијената.

Главни разлог за коришћење chunked transfer је динамичко генерисање садржаја. Када сервер генерише одговор на основу упита бази података, спољног API-ја или дуготрајног израчунавања, не може унапред знати величину резултата. Уместо да баферује цео одговор у меморији (што је ризично за велике количине), сервер укључује Transfer-Encoding: chunked и шаље податке како су спремни. Ово је посебно важно за сервере са ограниченом меморијом и за одговоре чија величина може бити веома велика — од 100 MB и више.

Разлика између HTTP/1.1 chunked и HTTP/2

У HTTP/2 механизам chunked transfer као такав не постоји, јер протокол користи мултиплексирање токова на нивоу оквира. У HTTP/2 подаци било које величине се преносе у DATA оквирима, а величина тела одговора не мора да се унапред декларише — ток се може затворити у било ком тренутку. Модерни сервери аутоматски конвертују chunked одговоре HTTP/1.1 у еквивалентни streaming пренос при проксирању на HTTP/2 upstream. Chunked Transfer остаје актуелан за HTTP/1.1 конекције.

Како ради пренос у чанковима

Када сервер одлучи да користи Chunked Transfer, не израчунава Content-Length, већ шаље заглавље Transfer-Encoding: chunked. Затим се тело одговора формира као низ чанкова. Сваки чанк почиње редом који садржи величину чанка у хексадецималном формату (без префикса 0x), након чега следи CRLF ( ). Затим долазе подаци чанка наведене величине, завршени CRLF. Последњи чанк има величину 0, након чега могу уследити trailer заглавља.

Хексадецимална величина омогућава пренос чанкова било које величине — од 1 бајта до теоријски неограниченог обима. У пракси величину чанка бира сервер: типичне вредности су 4 KB, 8 KB или 16 KB. Оптимална величина чанка је умножак величине TCP сегмента (обично 1460 бајтова за Ethernet) како би се минимизирала фрагментација на транспортном нивоу. Nginx подразумевано користи чанкове од 4 KB, Apache — од 8 KB.

Клијент који је примио Transfer-Encoding: chunked дужан је да чита одговор чанк по чанк до завршног нултог чанка. Ако клијент не подржава chunked transfer, сервер не може користити овај режим. У пракси сви модерни HTTP клијенти — прегледачи, OkHttp, URLSession, curl — у потпуности подржавају chunked одговоре. Streaming читање омогућава клијенту да почне обраду података пре него што прими комплетан одговор, што је критично за перформансе.

Елемент чанкаФорматПример
Величина чанкаHEX + CRLF1000
Подаци чанка[величина бајтова] + CRLF[4096 бајтова података]
Завршни чанк0 0
Trailer (опционално)Заглавља + CRLFExpires: Wed, 21 Oct 2025

Trailer заглавља у Chunked Transfer

Chunked Transfer подржава trailer заглавља — додатна HTTP заглавља која се преносе након последњег чанка. Ово је корисно за метаподатке који постају познати тек након завршетка генерисања одговора: на пример, Content-MD5 или X-Compression-Ratio. Trailer заглавља морају бити декларисана у заглављу Trailer: Content-MD5, X-Compression-Ratio. У пракси trailer се ретко користе — већина сервера их не укључује у одговоре.

Формат chunked одговора

Chunked одговор има строго дефинисану структуру коју клијент мора правилно да рашчлани. Размотримо комплетан пример HTTP одговора са Transfer-Encoding: chunked. Након заглавља и празног реда почиње тело одговора. Структура тела представља низ: величина_чанка подаци величина_чанка подаци ... до 0 . Свака величина се преноси у хексадецималном бројевном систему ASCII знацима.

Пример одговора сервера са Chunked Transfer:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked

7
Hello
6
World!
0

У овом примеру сервер преноси стринг „Hello World!” у два чанка. Први чанк величине 7 бајтова садржи „Hello ”, други — 6 бајтова „World!”. Клијент сакупља податке из оба чанка и добија комплетан стринг. Важно: величина чанка укључује само податке, не укључујући CRLF раздвајаче самих чанкова. Завршни празан чанк (0 ) обавештава клијента о крају преноса.

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

Рашчлањивање chunked одговора у OkHttp

OkHttp у потпуности апстрахује програмера од детаља Chunked Transfer-а. При пријему одговора са Transfer-Encoding: chunked, OkHttp аутоматски сакупља чанкове и пружа програмеру комплетно тело одговора кроз response.body?.string(). За streaming обраду користи се response.body?.source() који враћа BufferedSource и омогућава читање података како пристижу. Програмер не мора ручно да рашчлањује hex величине и CRLF — библиотека то ради аутоматски.

Chunked Transfer vs Content-Length

Content-Length и Transfer-Encoding: chunked су два међусобно искључива начина за одређивање величине тела HTTP поруке. Content-Length је заглавље које садржи тачну величину тела у бајтовима. Обавезно је за одговоре чија је величина позната унапред и за захтеве са телом (POST, PUT). Content-Length омогућава клијенту да унапред издвоји бафер одговарајуће величине и провери да ли су сви подаци примљени.

Chunked Transfer се користи када величина тела није унапред позната. Ово се дешава у три главна сценарија: динамичко генерисање садржаја (на пример, упит бази података чији резултат још није примљен), streaming пренос великих фајлова (како не би баферовао цео фајл у меморији) и Server-Sent Events (SSE) за пренос догађаја у реалном времену. Избор између Content-Length и chunked је одговорност сервера. Ако сервер зна величину пре почетка преноса, треба да користи Content-Length као једноставнији и предвидљивији механизам.

Спецификација HTTP/1.1 забрањује истовремену употребу Content-Length и Transfer-Encoding: chunked. Ако сервер шаље оба заглавља, клијент мора да игнорише Content-Length и обрађује одговор као chunked. Приоритет Transfer-Encoding над Content-Length утврђен је у RFC 7230 за случајеве када прокси сервер мења тело одговора и не може да сачува оригинални Content-Length. Неки стари HTTP клијенти неисправно обрађују ову ситуацију, али модерне имплементације прате спецификацију.

Када Content-Length није могућ

Постоје сценарији у којима Content-Length принципијелно не може бити израчунат унапред. Динамички извештаји који се генеришу на захтев корисника са филтрирањем и агрегацијом — сервер не зна обим података до завршетка упита бази података. Streaming видео преношен са камере у реалном времену — величина је бесконачна. SSE и long polling за обавештења — одговор може трајати неодређено дуго. У свим овим случајевима Chunked Transfer је једини исправан механизам.

Streaming на бази chunked transfer

Chunked Transfer лежи у основи многих streaming технологија на вебу. Најпознатија је Server-Sent Events (SSE), где сервер шаље догађаје клијенту преко једне HTTP конекције са Transfer-Encoding: chunked. SSE користи посебан текст формат (data: порука ), али транспортни ниво је обичан chunked transfer. Прегледач прима догађаје како их сервер шаље, не чекајући завршетак одговора.

Streaming аудио и видео такође се ослања на Chunked Transfer. Медија сервери, као што су Nginx RTMP и Wowza Streaming Engine, шаљу медија податке у чанковима преко HTTP-а. Плејер на страни клијента почиње репродукцију када је примљен први чанк, не чекајући потпуно учитавање фајла. Ово смањује време до почетка репродукције (Time to First Frame) са десетина секунди на 1-2 секунде. YouTube и Netflix користе управо овај приступ за своје HTTP токове.

У развоју мобилних апликација, Chunked Transfer се користи за пренос великих количина података без учитавања целог одговора у меморију. При учитавању слика преко Coil или Glide на Android-у, библиотеке читају streaming податке у чанковима и постепено декодирају слику. Ово омогућава приказ великих слика (10+ MB) без OutOfMemoryError. OkHttp подржава streaming читање кроз response.body?.byteStream() који враћа InputStream и чита податке чанк по чанк.

Chunked transfer у gRPC и GraphQL

gRPC користи HTTP/2, где је streaming пренос уграђен на нивоу протокола и не захтева посебан chunked механизам. GraphQL сервери који раде преко HTTP/1.1 могу користити Chunked Transfer за streaming пренос резултата претплата (subscriptions). Apollo Server и Hasura шаљу chunked одговоре за GraphQL претплате, преносећи догађаје како настају. Клијент добија ажурирања у реалном времену без потребе за polling-ом.

Предности и ограничења

Chunked Transfer пружа важне предности за веб апликације. Тренутно слање података — сервер не баферује одговор пре слања, смањујући кашњење (latency) до првог бајта. Streaming обрада — клијент може почети обраду података како пристижу, не чекајући потпуно учитавање. Без ограничења меморије — сервер не чува комплетан одговор у меморији, што је критично за велике количине података. Могућност преноса бесконачних токова — SSE, live видео, мониторинг.

Међутим, Chunked Transfer има ограничења. Додатни трошак за сваки чанк износи 6-12 бајтова за величину + CRLF, што за велики број малих чанкова (на пример, по 100 бајтова) може повећати величину одговора за 10-15%. Немогућност навођења тачне величине — клијент не може унапред издвојити бафер или показати траку напретка. Проблеми са прокси серверима — неки стари прокси не подржавају chunked transfer и не могу кеширати такве одговоре. Недовољна подршка за настављак прекинутог преузимања — за делимично примљене chunked одговоре не може се упутити Range захтев.

Према HTTP Archive, 2025, око 35% свих HTTP одговора користи Transfer-Encoding: chunked. Међу њима преовлађују динамичке странице (60%), API одговори (25%) и медија токови (15%). Статички фајлови скоро увек користе Content-Length, јер је њихова величина унапред позната. Удео chunked одговора постепено опада са ширењем HTTP/2, где је streaming пренос имплементиран на нивоу оквира без потребе за додатним заглављем Transfer-Encoding.

Практичне препоруке

У развоју мобилних апликација користите Chunked Transfer за учитавање великих фајлова (слике, видео) и за API захтеве који враћају велике низове података. OkHttp у потпуности подржава chunked transfer без додатног подешавања. За отпремање на сервер (upload) Chunked Transfer се не примењује — за то се Transfer-Encoding не користи за upload у HTTP/1.1. На iOS-у URLSession подржава и слање и пријем chunked података без посебне конфигурације. Streaming парсирање JSON-а (на пример, преко Jackson Streaming API или Moshi) омогућава обраду великих JSON низова како chunked ток пристиже.

Често постављана питања

Како сервер укључује Chunked Transfer?

Сервер укључује Chunked Transfer аутоматски када величина одговора није позната. Nginx додаје Transfer-Encoding: chunked ако није постављен Content-Length. У Spring Boot-у StreamingResponseBody и SseEmitter аутоматски користе chunked transfer. У Node.js Express одговор постаје chunked ако се позову res.write() и res.end() без Content-Length.

Могу ли се Content-Length и chunked користити истовремено?

Не, спецификација HTTP/1.1 забрањује истовремену употребу Content-Length и Transfer-Encoding: chunked. Ако сервер шаље оба заглавља, клијент мора да игнорише Content-Length и обрађује одговор као chunked. Ово правило је утврђено у RFC 7230 ради компатибилности са прокси серверима који могу мењати тело одговора.

Која величина чанка је оптимална?

Оптимална величина чанка зависи од сценарија. За обичне веб странице — 4-8 KB. За streaming пренос видеа — 16-64 KB. За SSE — минимални чанкови од 1-2 KB за смањење кашњења. Величина чанка треба да буде умножак величине TCP сегмента (1460 бајтова за Ethernet) ради минимизације фрагментације на транспортном нивоу.

Да ли Chunked Transfer ради преко проксија?

Модерни прокси сервери (Nginx, HAProxy, Envoy) подржавају Chunked Transfer. Прокси може преносити чанкове даље без баферовања (streaming) или баферовати цео одговор и поново га послати са Content-Length. Стари прокси могу баферовати chunked одговор до завршетка, што повећава кашњење. HTTP/2 решава овај проблем на нивоу протокола.

По чему се Chunked Transfer разликује од HTTP chunked encoding?

То је исто. Chunked Transfer је пуни назив механизма из спецификације HTTP/1.1. HTTP chunked encoding је исто, понекад се користи у документацији библиотека. Transfer-Encoding: chunked је заглавље које укључује овај режим. Сва три термина описују исти механизам преноса података у деловима.

Резиме

  • Chunked Transfer — механизам HTTP/1.1 који преноси тело одговора у чанковима без претходног навођења Content-Length.
  • Transfer-Encoding: chunked — заглавље које укључује chunked пренос; сваки чанк садржи hex величину, податке и CRLF.
  • Завршни чанк нулте величине сигнализира крај преноса, након чега могу уследити trailer заглавља.
  • Dynamic content streaming — основна примена: динамичке странице, SSE, streaming аудио/видео, дуги извештаји.
  • Content-Length и chunked су међусобно искључиви — спецификација забрањује истовремену употребу ових заглавља.
  • Предности — смањење кашњења, уштеда меморије, могућност преноса бесконачних токова и streaming обрада на клијенту.
  • Ограничења — додатни трошак на заглавља чанкова, немогућност приказа напретка, проблеми са старим прокси серверима.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође