Chunked Transfer — είναι ένας μηχανισμός του πρωτοκόλλου HTTP κατά τον οποίο ο διακομιστής μεταδίδει το σώμα της απάντησης σε ξεχωριστά τμήματα (chunks), χωρίς να υποδεικνύει εκ των προτέρων το συνολικό μέγεθος των δεδομένων. Κάθε chunk περιέχει το δικό του μέγεθος σε δεκαεξαδική μορφή και δεδομένα καθορισμένου μήκους, και τελειώνει με ένα τελικό chunk μηδενικού μεγέθους. Σύμφωνα με τα MDN Web Docs, 2025, η Transfer-Encoding: chunked ενεργοποιείται αυτόματα από τον διακομιστή όταν το μέγεθος της απάντησης δεν είναι γνωστό εκ των προτέρων — για παράδειγμα, κατά τη δημιουργία περιεχομένου εν κινήσει ή τη streaming μετάδοση δεδομένων.
Κύρια σημεία
Chunked Transfer είναι ένας μηχανισμός HTTP που ορίζεται στην προδιαγραφή HTTP/1.1 (RFC 7230, ενότητα 4.1) και επιτρέπει στον διακομιστή να στέλνει το σώμα της απάντησης σε μέρη χωρίς να αναφέρει το συνολικό Content-Length. Αντί να υπολογίζει το μέγεθος της απάντησης πριν από την αποστολή, ο διακομιστής ξεκινά αμέσως τη μετάδοση, στέλνοντας δεδομένα σε τμήματα μόλις είναι έτοιμα. Κάθε τμήμα συνοδεύεται από τη δική του κεφαλίδα μεγέθους, επιτρέποντας στον πελάτη να συναρμολογήσει την απάντηση από κομμάτια.
Ο μηχανισμός ενεργοποιείται από την κεφαλίδα Transfer-Encoding: chunked. Όταν ο πελάτης βλέπει αυτήν την κεφαλίδα στην απάντηση, γνωρίζει ότι το σώμα θα μεταδοθεί σε chunks και πρέπει να διαβάζει την απάντηση σε έναν βρόχο: να διαβάσει το μέγεθος του chunk, στη συνέχεια τα δεδομένα του καθορισμένου μεγέθους και μετά να επαναλάβει. Η διαδικασία τελειώνει όταν συναντηθεί ένα chunk μηδενικού μεγέθους. Το Chunked Transfer είναι υποχρεωτικό μέρος του HTTP/1.1 και υποστηρίζεται από όλους τους σύγχρονους διακομιστές ιστού και πελάτες HTTP.
Ο κύριος λόγος χρήσης του chunked transfer είναι η δυναμική δημιουργία περιεχομένου. Όταν ο διακομιστής δημιουργεί μια απάντηση βάσει ενός ερωτήματος βάσης δεδομένων, εξωτερικού API ή μακροχρόνιου υπολογισμού, δεν μπορεί να γνωρίζει εκ των προτέρων το μέγεθος του αποτελέσματος. Αντί να αποθηκεύει προσωρινά ολόκληρη την απάντηση στη μνήμη (που είναι επικίνδυνο για μεγάλους όγκους), ο διακομιστής ενεργοποιεί το Transfer-Encoding: chunked και στέλνει δεδομένα μόλις είναι έτοιμα. Αυτό είναι ιδιαίτερα σημαντικό για διακομιστές με περιορισμένη μνήμη και για απαντήσεις των οποίων το μέγεθος μπορεί να είναι πολύ μεγάλο — από 100 MB και άνω.
Στο 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. Στη συνέχεια, το σώμα της απάντησης σχηματίζεται ως μια ακολουθία chunks. Κάθε chunk ξεκινά με μια γραμμή που περιέχει το μέγεθος του chunk σε δεκαεξαδική μορφή (χωρίς το πρόθεμα 0x), ακολουθούμενη από CRLF ( ). Στη συνέχεια έρχονται τα δεδομένα του chunk του καθορισμένου μεγέθους, που τελειώνουν με CRLF. Το τελευταίο chunk έχει μέγεθος 0, μετά το οποίο μπορεί να ακολουθήσουν κεφαλίδες trailer.
Το δεκαεξαδικό μέγεθος επιτρέπει τη μετάδοση chunks οποιουδήποτε μεγέθους — από 1 byte έως θεωρητικά απεριόριστο όγκο. Στην πράξη, το μέγεθος του chunk επιλέγεται από τον διακομιστή: τυπικές τιμές είναι 4 KB, 8 KB ή 16 KB. Το βέλτιστο μέγεθος chunk είναι πολλαπλάσιο του μεγέθους του τμήματος TCP (συνήθως 1460 byte για Ethernet) για την ελαχιστοποίηση του κατακερματισμού στο επίπεδο μεταφοράς. Ο Nginx χρησιμοποιεί από προεπιλογή chunks των 4 KB, ο Apache — των 8 KB.
Ο πελάτης που έλαβε Transfer-Encoding: chunked είναι υποχρεωμένος να διαβάζει την απάντηση chunk προς chunk μέχρι το τελικό μηδενικό chunk. Εάν ο πελάτης δεν υποστηρίζει chunked transfer, ο διακομιστής δεν μπορεί να χρησιμοποιήσει αυτήν τη λειτουργία. Στην πράξη, όλοι οι σύγχρονοι πελάτες HTTP — προγράμματα περιήγησης, OkHttp, URLSession, curl — υποστηρίζουν πλήρως τις chunked απαντήσεις. Η streaming ανάγνωση επιτρέπει στον πελάτη να ξεκινήσει την επεξεργασία δεδομένων πριν λάβει την πλήρη απάντηση, κάτι που είναι κρίσιμο για την απόδοση.
| Στοιχείο chunk | Μορφή | Παράδειγμα |
|---|---|---|
| Μέγεθος chunk | HEX + CRLF | 1000 |
| Δεδομένα chunk | [μέγεθος byte] + CRLF | [4096 byte δεδομένων] |
| Τελικό chunk | 0 | 0 |
| Trailer (προαιρετικό) | Κεφαλίδες + CRLF | Expires: Wed, 21 Oct 2025 |
Το Chunked Transfer υποστηρίζει κεφαλίδες trailer — πρόσθετες κεφαλίδες HTTP που μεταδίδονται μετά το τελευταίο chunk. Αυτό είναι χρήσιμο για μεταδεδομένα που γίνονται γνωστά μόνο μετά την ολοκλήρωση της δημιουργίας της απάντησης: για παράδειγμα, Content-MD5 ή X-Compression-Ratio. Οι κεφαλίδες trailer πρέπει να δηλώνονται στην κεφαλίδα Trailer: Content-MD5, X-Compression-Ratio. Στην πράξη, τα trailer χρησιμοποιούνται σπάνια — οι περισσότεροι διακομιστές δεν τα συμπεριλαμβάνουν στις απαντήσεις τους.
Η chunked απάντηση έχει αυστηρά καθορισμένη δομή που ο πελάτης πρέπει να αναλύσει σωστά. Ας εξετάσουμε ένα πλήρες παράδειγμα HTTP απάντησης με Transfer-Encoding: chunked. Μετά τις κεφαλίδες και την κενή γραμμή, αρχίζει το σώμα της απάντησης. Η δομή του σώματος είναι μια ακολουθία: μέγεθος_chunk δεδομένα μέγεθος_chunk δεδομένα ... έως 0 . Κάθε μέγεθος μεταδίδεται στο δεκαεξαδικό σύστημα αρίθμησης με χαρακτήρες ASCII.
Παράδειγμα απάντησης διακομιστή με Chunked Transfer:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
7
Hello
6
World!
0
Σε αυτό το παράδειγμα, ο διακομιστής μεταδίδει τη συμβολοσειρά “Hello World!” σε δύο chunks. Το πρώτο chunk μεγέθους 7 byte περιέχει “Hello ”, το δεύτερο — 6 byte “World!”. Ο πελάτης συλλέγει δεδομένα και από τα δύο chunks και λαμβάνει την πλήρη συμβολοσειρά. Σημαντικό: το μέγεθος chunk περιλαμβάνει μόνο τα δεδομένα, όχι τους διαχωριστές CRLF των ίδιων των chunks. Το τελικό κενό chunk (0 ) ειδοποιεί τον πελάτη για το τέλος της μετάδοσης.
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 αφαιρεί πλήρως τον προγραμματιστή από τις λεπτομέρειες του Chunked Transfer. Κατά τη λήψη μιας απάντησης με Transfer-Encoding: chunked, το OkHttp συλλέγει αυτόματα τα chunks και παρέχει στον προγραμματιστή το πλήρες σώμα της απάντησης μέσω του response.body?.string(). Για streaming επεξεργασία χρησιμοποιείται το response.body?.source(), το οποίο επιστρέφει ένα BufferedSource και επιτρέπει την ανάγνωση δεδομένων καθώς φτάνουν. Ο προγραμματιστής δεν χρειάζεται να αναλύει χειροκίνητα τα hex μεγέθη και τα CRLF — η βιβλιοθήκη το κάνει αυτόματα.
Το Content-Length και το Transfer-Encoding: chunked είναι δύο αμοιβαία αποκλειόμενοι τρόποι καθορισμού του μεγέθους του σώματος ενός μηνύματος HTTP. Content-Length είναι μια κεφαλίδα που περιέχει το ακριβές μέγεθος του σώματος σε byte. Είναι υποχρεωτικό για απαντήσεις των οποίων το μέγεθος είναι γνωστό εκ των προτέρων και για αιτήματα με σώμα (POST, PUT). Το Content-Length επιτρέπει στον πελάτη να δεσμεύσει εκ των προτέρων ένα buffer κατάλληλου μεγέθους και να ελέγξει εάν έχουν ληφθεί όλα τα δεδομένα.
Το 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 κατ' αρχήν δεν μπορεί να υπολογιστεί εκ των προτέρων. Δυναμικές αναφορές που δημιουργούνται κατόπιν αιτήματος χρήστη με φιλτράρισμα και συγκέντρωση — ο διακομιστής δεν γνωρίζει τον όγκο των δεδομένων μέχρι την ολοκλήρωση του ερωτήματος βάσης δεδομένων. Streaming βίντεο που μεταδίδεται από κάμερα σε πραγματικό χρόνο — το μέγεθος είναι άπειρο. SSE και long polling για ειδοποιήσεις — η απάντηση μπορεί να διαρκέσει απεριόριστα. Σε όλες αυτές τις περιπτώσεις, το 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 στέλνουν δεδομένα πολυμέσων σε chunks μέσω HTTP. Ο αναπαραγωγέας από την πλευρά του πελάτη ξεκινά την αναπαραγωγή όταν ληφθεί το πρώτο chunk, χωρίς να περιμένει την πλήρη φόρτωση του αρχείου. Αυτό μειώνει τον χρόνο έως την έναρξη αναπαραγωγής (Time to First Frame) από δεκάδες δευτερόλεπτα σε 1-2 δευτερόλεπτα. Το YouTube και το Netflix χρησιμοποιούν ακριβώς αυτήν την προσέγγιση για τις ροές HTTP τους.
Στην ανάπτυξη εφαρμογών για κινητά, το Chunked Transfer χρησιμοποιείται για τη μετάδοση μεγάλων όγκων δεδομένων χωρίς φόρτωση ολόκληρης της απάντησης στη μνήμη. Κατά τη φόρτωση εικόνων μέσω Coil ή Glide σε Android, οι βιβλιοθήκες διαβάζουν streaming δεδομένα σε chunks και αποκωδικοποιούν σταδιακά την εικόνα. Αυτό επιτρέπει την εμφάνιση μεγάλων εικόνων (10+ MB) χωρίς OutOfMemoryError. Το OkHttp υποστηρίζει streaming ανάγνωση μέσω του response.body?.byteStream(), το οποίο επιστρέφει ένα InputStream που διαβάζει δεδομένα chunk προς chunk.
Το gRPC χρησιμοποιεί HTTP/2, όπου η streaming μετάδοση είναι ενσωματωμένη σε επίπεδο πρωτοκόλλου και δεν απαιτεί ξεχωριστό μηχανισμό chunked. Οι διακομιστές GraphQL που λειτουργούν μέσω HTTP/1.1 μπορούν να χρησιμοποιήσουν Chunked Transfer για streaming μετάδοση αποτελεσμάτων συνδρομών (subscriptions). Ο Apollo Server και το Hasura στέλνουν chunked απαντήσεις για συνδρομές GraphQL, μεταδίδοντας συμβάντα καθώς συμβαίνουν. Ο πελάτης λαμβάνει ενημερώσεις σε πραγματικό χρόνο χωρίς την ανάγκη polling.
Το Chunked Transfer παρέχει σημαντικά πλεονεκτήματα για εφαρμογές web. Άμεση αποστολή δεδομένων — ο διακομιστής δεν αποθηκεύει προσωρινά την απάντηση πριν από την αποστολή, μειώνοντας την καθυστέρηση (latency) έως το πρώτο byte. Streaming επεξεργασία — ο πελάτης μπορεί να ξεκινήσει την επεξεργασία δεδομένων καθώς φτάνουν, χωρίς να περιμένει την πλήρη φόρτωση. Χωρίς περιορισμούς μνήμης — ο διακομιστής δεν αποθηκεύει ολόκληρη την απάντηση στη μνήμη, κάτι που είναι κρίσιμο για μεγάλους όγκους δεδομένων. Δυνατότητα μετάδοσης ατελείωτων ροών — SSE, ζωντανό βίντεο, παρακολούθηση.
Ωστόσο, το Chunked Transfer έχει περιορισμούς. Επιβάρυνση για κάθε chunk είναι 6-12 byte για μέγεθος + CRLF, που για μεγάλο αριθμό μικρών chunks (για παράδειγμα, 100 byte) μπορεί να αυξήσει το μέγεθος της απάντησης κατά 10-15%. Αδυναμία αναφοράς ακριβούς μεγέθους — ο πελάτης δεν μπορεί να δεσμεύσει εκ των προτέρων buffer ή να εμφανίσει γραμμή προόδου. Προβλήματα με διακομιστές μεσολάβησης — ορισμένοι παλαιότεροι διακομιστές μεσολάβησης δεν υποστηρίζουν 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 όταν το μέγεθος της απάντησης είναι άγνωστο. Ο Nginx προσθέτει Transfer-Encoding: chunked εάν δεν έχει οριστεί Content-Length. Στο Spring Boot, τα StreamingResponseBody και SseEmitter χρησιμοποιούν αυτόματα chunked transfer. Στο Node.js Express, η απάντηση γίνεται chunked εάν κληθούν τα res.write() και res.end() χωρίς Content-Length.
Όχι, η προδιαγραφή HTTP/1.1 απαγορεύει την ταυτόχρονη χρήση Content-Length και Transfer-Encoding: chunked. Εάν ο διακομιστής στείλει και τις δύο κεφαλίδες, ο πελάτης πρέπει να αγνοήσει το Content-Length και να επεξεργαστεί την απάντηση ως chunked. Αυτός ο κανόνας καθορίστηκε στο RFC 7230 για συμβατότητα με διακομιστές μεσολάβησης που μπορούν να τροποποιήσουν το σώμα της απάντησης.
Το βέλτιστο μέγεθος chunk εξαρτάται από το σενάριο. Για συνηθισμένες ιστοσελίδες — 4-8 KB. Για streaming βίντεο — 16-64 KB. Για SSE — ελάχιστα chunks των 1-2 KB για μείωση της καθυστέρησης. Το μέγεθος chunk πρέπει να είναι πολλαπλάσιο του μεγέθους τμήματος TCP (1460 byte για Ethernet) για ελαχιστοποίηση του κατακερματισμού στο επίπεδο μεταφοράς.
Οι σύγχρονοι διακομιστές μεσολάβησης (Nginx, HAProxy, Envoy) υποστηρίζουν το Chunked Transfer. Ο διακομιστής μεσολάβησης μπορεί να προωθήσει τα chunks χωρίς προσωρινή αποθήκευση (streaming) ή να αποθηκεύσει προσωρινά ολόκληρη την απάντηση και να την ξαναστείλει με Content-Length. Παλαιότεροι διακομιστές μεσολάβησης μπορεί να αποθηκεύουν προσωρινά την chunked απάντηση μέχρι την ολοκλήρωση, αυξάνοντας την καθυστέρηση. Το HTTP/2 λύνει αυτό το πρόβλημα σε επίπεδο πρωτοκόλλου.
Είναι το ίδιο πράγμα. Chunked Transfer είναι η πλήρης ονομασία του μηχανισμού από την προδιαγραφή HTTP/1.1. HTTP chunked encoding είναι το ίδιο, μερικές φορές χρησιμοποιείται στην τεκμηρίωση βιβλιοθηκών. Transfer-Encoding: chunked είναι η κεφαλίδα που ενεργοποιεί αυτήν τη λειτουργία. Και οι τρεις όροι περιγράφουν τον ίδιο μηχανισμό μετάδοσης δεδομένων σε μέρη.
Περίληψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης