Last-Modified — HTTP επικεφαλίδα απόκρισης που υποδεικνύει την ημερομηνία και ώρα της τελευταίας τροποποίησης ενός πόρου στον διακομιστή, επιτρέποντας στον πελάτη να εκτελεί υπό αίρεση αιτήματα μέσω του If-Modified-Since. Εάν ο πόρος δεν έχει αλλάξει από την αναφερόμενη ημερομηνία, ο διακομιστής επιστρέφει 304 Not Modified χωρίς μετάδοση σώματος απόκρισης, εξοικονομώντας σημαντικά εύρος ζώνης. Σύμφωνα με το RFC 7232 (IETF, 2014), τα υπό αίρεση αιτήματα με Last-Modified μειώνουν τον χρόνο φόρτωσης σελίδων κατά 30-60% σε επαναλαμβανόμενες επισκέψεις. Η επικεφαλίδα υποστηρίζεται αυτόματα από τους περισσότερους HTTP διακομιστές και διακομιστές μεσολάβησης.
Βασικά σημεία
Last-Modified — είναι μια HTTP επικεφαλίδα που ανήκει στην ομάδα επικεφαλίδων υπό αίρεση αιτημάτων (conditional requests). Ο διακομιστής την προσθέτει στην απόκριση GET ή HEAD, υποδεικνύοντας την ημερομηνία και ώρα της τελευταίας τροποποίησης του ζητούμενου πόρου σε μορφή HTTP-date: Last-Modified: Wed, 02 Jul 2025 14:30:00 GMT. Ο πελάτης (πρόγραμμα περιήγησης, εφαρμογή κινητού, διακομιστής μεσολάβησης) αποθηκεύει αυτήν την ημερομηνία μαζί με τον αποθηκευμένο πόρο. Σε επαναλαμβανόμενο αίτημα, ο πελάτης στέλνει την επικεφαλίδα If-Modified-Since με την ίδια ημερομηνία και ο διακομιστής τη συγκρίνει με τον τρέχοντα χρόνο τροποποίησης του πόρου.
Το πρωτόκολλο υπό αίρεση αιτημάτων με Last-Modified ορίζεται στο RFC 7232 και υποστηρίζεται από όλους τους σύγχρονους HTTP διακομιστές. Η μορφή ημερομηνίας είναι αυστηρά καθορισμένη — μόνο GMT (Greenwich Mean Time) χωρίς αναφορά ζώνης ώρας. Ο διακομιστής πρέπει να επιστρέφει ημερομηνία σε τρεις δυνατές μορφές: RFC 1123 (κανονική), RFC 850 (παλαιότερη) ή ANSI C asctime. Στην πράξη, σχεδόν όλοι οι διακομιστές χρησιμοποιούν τη μορφή RFC 1123 με σταθερό μήκος 29 χαρακτήρων.
Το Last-Modified ανήκει στην κατηγορία μηχανισμών επικύρωσης προσωρινής αποθήκευσης: δεν λέει στον πελάτη εάν μπορεί να αποθηκεύσει προσωρινά την απόκριση, αλλά παρέχει ένα εργαλείο για έλεγχο ενημερότητας ενός ήδη αποθηκευμένου πόρου. Η πολιτική προσωρινής αποθήκευσης ορίζεται ξεχωριστά μέσω της επικεφαλίδας Cache-Control. Σύμφωνα με έρευνα της Akamai (2025), η σωστή ρύθμιση του Last-Modified μαζί με το Cache-Control μειώνει το φορτίο στους αρχικούς διακομιστές έως και 70% για στατικό περιεχόμενο.
Η επικεφαλίδα Last-Modified ορίστηκε ήδη στο HTTP/1.0 (RFC 1945, 1996) και έγινε ένας από τους πρώτους μηχανισμούς διαχείρισης προσωρινής αποθήκευσης στον ιστό. Πριν από την εμφάνιση του ETag στο HTTP/1.1, ήταν ο μοναδικός τρόπος εκτέλεσης υπό αίρεση αιτημάτων. Παρά την ηλικία της, η επικεφαλίδα παραμένει επίκαιρη χάρη στην απλότητά της — ο διακομιστής δεν χρειάζεται να υπολογίσει hash περιεχομένου, αρκεί να διαβάσει το timestamp αρχείου από το σύστημα αρχείων ή το πεδίο updated_at από τη βάση δεδομένων.
Ο πλήρης κύκλος περιλαμβάνει τρία στάδια. Στο πρώτο αίτημα, ο διακομιστής επιστρέφει τον πόρο με την επικεφαλίδα Last-Modified και HTTP κατάσταση 200 OK. Ο πελάτης αποθηκεύει προσωρινά την απόκριση μαζί με την ημερομηνία. Σε επαναλαμβανόμενο αίτημα, ο πελάτης στέλνει την επικεφαλίδα If-Modified-Since με την αποθηκευμένη ημερομηνία. Ο διακομιστής συγκρίνει αυτήν την ημερομηνία με τον τρέχοντα χρόνο τροποποίησης του πόρου. Εάν ο πόρος δεν έχει τροποποιηθεί — επιστρέφεται 304 Not Modified με κενό σώμα. Εάν έχει τροποποιηθεί — 200 OK με νέα δεδομένα και νέο Last-Modified.
// Πρώτο αίτημα — ο διακομιστής επιστρέφει τον πόρο με ημερομηνία
HTTP/1.1 200 OK
Content-Type: application/json
Last-Modified: Wed, 02 Jul 2025 14:30:00 GMT
[{"id": 1, "name": "Alice"}]
// Επαναλαμβανόμενο αίτημα — ο πελάτης στέλνει την αποθηκευμένη ημερομηνία
GET /api/users HTTP/1.1
Host: example.com
If-Modified-Since: Wed, 02 Jul 2025 14:30:00 GMT
// Απόκριση — τα δεδομένα δεν έχουν αλλάξει
HTTP/1.1 304 Not Modified
Για εφαρμογές κινητών, το Last-Modified είναι ιδιαίτερα χρήσιμο κατά τον συγχρονισμό δεδομένων. Η εφαρμογή αποθηκεύει την ημερομηνία της τελευταίας επιτυχημένης ενημέρωσης και τη στέλνει στον διακομιστή στο If-Modified-Since. Εάν υπάρχουν περισσότερα δεδομένα ή έχουν αλλάξει — ο διακομιστής επιστρέφει το πλήρες σύνολο. Εάν όχι — 304 και η εφαρμογή χρησιμοποιεί το τοπικό αντίγραφο. Τα OkHttp και URLSession υποστηρίζουν αυτόν τον μηχανισμό αυτόματα μέσω ενσωματωμένων συστημάτων προσωρινής αποθήκευσης.
Για στατικά αρχεία, οι Nginx και Apache λαμβάνουν την ημερομηνία από τα χαρακτηριστικά του συστήματος αρχείων — mtime (χρόνος τροποποίησης). Για δυναμικό περιεχόμενο, ο κώδικας του διακομιστή πρέπει να ορίζει ρητά το Last-Modified βάσει επιχειρηματικής λογικής: το πεδίο updated_at από τη βάση δεδομένων, η ημερομηνία του τελευταίου commit στο Git, το timestamp κατασκευής του artifact. Εάν το Last-Modified δεν έχει οριστεί ρητά, ο διακομιστής μπορεί να μην επιστρέφει καθόλου την επικεφαλίδα και ο πελάτης δεν θα μπορεί να εκτελεί υπό αίρεση αιτήματα βάσει ημερομηνίας.
Το Last-Modified και το ETag εκτελούν παρόμοια εργασία — επιτρέπουν στον πελάτη να ελέγξει την ενημερότητα της προσωρινής μνήμης — αλλά έχουν θεμελιώδεις διαφορές. Το Last-Modified χρησιμοποιεί χρονική σήμανση, το ETag — μοναδικό αναγνωριστικό έκδοσης. Κάθε προσέγγιση έχει τα σενάριά της όπου είναι πιο αποτελεσματική και η σύσταση της προδιαγραφής HTTP είναι να χρησιμοποιούνται και οι δύο επικεφαλίδες μαζί.
| Κριτήριο | Last-Modified | ETag |
|---|---|---|
| Ουσία | Ημερομηνία τελευταίας τροποποίησης | Μοναδικό αναγνωριστικό έκδοσης |
| Ακρίβεια | Μέχρι δευτερόλεπτο | Μέχρι bit (hash) |
| Πολυπλοκότητα υλοποίησης | Χαμηλή — αυτόματα από σύστημα αρχείων | Μεσαία — απαιτεί υπολογισμό hash |
| Clustered διακομιστές | Πρόβλημα: το mtime μπορεί να διαφέρει στους κόμβους | Σταθερό με ίδια δεδομένα στους κόμβους |
| Υποστήριξη περιοχών | Δεν επηρεάζει τα Range requests | Απαιτεί ισχυρό ETag για περιοχές |
| Σύσταση | Για στατικά και απλά API | Για API όπου απαιτείται ακριβής έλεγχος |
Το κύριο πλεονέκτημα του Last-Modified είναι η απλότητα. Ο διακομιστής δεν χρειάζεται να υπολογίσει hash περιεχομένου, εξοικονομώντας CPU πόρους σε κάθε αίτημα. Για έργα υψηλής φόρτισης που εξυπηρετούν στατικά αρχεία ή δεδομένα με σαφείς χρονικές σημάνσεις, το Last-Modified παραμένει η βέλτιστη επιλογή. Το ETag προσφέρει απόλυτη ακρίβεια — μια αλλαγή ενός γράμματος σε απόκριση JSON θα αλλάξει το ETag, αλλά μπορεί να μην αλλάξει την ημερομηνία (εάν το αρχείο αντικατασταθεί με την ίδια έκδοση).
Η προδιαγραφή συνιστά την επιστροφή και των δύο επικεφαλίδων ταυτόχρονα. Ο διακομιστής περιλαμβάνει τόσο το Last-Modified όσο και το ETag στην απόκριση 200 OK. Ο πελάτης στέλνει και τις δύο υπό αίρεση επικεφαλίδες — If-Modified-Since και If-None-Match. Ο διακομιστής ελέγχει πρώτα το ETag (έχει προτεραιότητα), στη συνέχεια το Last-Modified. Εάν τουλάχιστον ένα σηματοδοτεί αλλαγή — επιστρέφεται πλήρης απόκριση. Αυτό παρέχει μέγιστη ευελιξία: το ETag εξασφαλίζει ακρίβεια, το Last-Modified — εφεδρικό έλεγχο για πελάτες που δεν υποστηρίζουν ETag.
Η ρύθμιση του Last-Modified εξαρτάται από τον τύπο διακομιστή. Για Nginx και Apache, το Last-Modified ορίζεται αυτόματα για στατικά αρχεία βάσει mtime. Για δυναμικές εφαρμογές, η επικεφαλίδα πρέπει να ορίζεται στον κώδικα του διακομιστή. Ας δούμε τη ρύθμιση σε δημοφιλείς πλατφόρμες.
// Express.js — ρύθμιση Last-Modified
app.get("/api/users", async (req, res) => {
const updatedAt = await getLastUpdate()
const ifModifiedSince = req.get("If-Modified-Since")
// Έλεγχος If-Modified-Since
if (ifModifiedSince && new Date(ifModifiedSince)
>= updatedAt) {
return res.status(304).end()
}
const users = await getUsers()
res.set("Last-Modified", updatedAt.toUTCString())
res.json(users)
})
Στο παράδειγμα με Express.js, ο διακομιστής λαμβάνει την ημερομηνία τελευταίας ενημέρωσης δεδομένων από τη βάση, ελέγχει το If-Modified-Since από τον πελάτη και εάν η προσωρινή μνήμη είναι έγκυρη επιστρέφει 304. Εάν τα δεδομένα έχουν αλλάξει — ορίζει νέο Last-Modified και επιστρέφει πλήρη απόκριση. Η toUTCString() μετατρέπει την ημερομηνία στην απαιτούμενη HTTP μορφή. Σε παραγωγή, αξίζει να προστεθεί προσωρινή αποθήκευση του updatedAt στο Redis για να μην εκτελείται ερώτημα στη βάση δεδομένων σε κάθε αίτημα.
Ο Nginx ορίζει αυτόματα το Last-Modified για στατικά αρχεία βάσει του χρόνου τελευταίας τροποποίησης του αρχείου. Η απενεργοποίηση ή αλλαγή της συμπεριφοράς μπορεί να γίνει με την οδηγία etag (απενεργοποίηση ETag) ή μέσω του module ngx_http_headers_module. Για αιτήματα μέσω διακομιστή μεσολάβησης προς το backend, το Last-Modified μεταφέρεται από την απόκριση upstream χωρίς αλλαγές. Σημαντικό: εάν το backend δεν επιστρέφει Last-Modified, ο Nginx δεν θα το προσθέσει αυτόματα για δυναμικές αποκρίσεις.
Το Last-Modified έχει αρκετούς γνωστούς περιορισμούς. Το κύριο — ακρίβεια έως δευτερόλεπτο. Εάν ένας πόρος έχει αλλάξει δύο φορές μέσα σε ένα δευτερόλεπτο, ο πελάτης μπορεί να χάσει τη νέα έκδοση. Στην πράξη, αυτό είναι σπάνιο σενάριο, αλλά για ενημερώσεις υψηλής συχνότητας (ροές τιμών, συνομιλίες) συνιστάται το ETag. Ο δεύτερος περιορισμός — πρόβλημα συσταδοποίησης: σε διαφορετικούς διακομιστές, το αρχείο μπορεί να έχει διαφορετικό mtime λόγω αντιγραφής ή ανάπτυξης, με αποτέλεσμα το Last-Modified να είναι ασυνεπές.
Ο τρίτος περιορισμός — η επεξεργασία του If-Modified-Since με ακρίβεια δευτερολέπτου μπορεί να οδηγήσει σε περιττά αιτήματα κατά τη συχνή επισκόπηση του διακομιστή. Εάν ο πελάτης στέλνει If-Modified-Since κάθε 500 ms, ο διακομιστής επιστρέφει 200 OK κάθε φορά, καθώς η ημερομηνία δεν έχει αλλάξει, αλλά ο πόρος έχει ήδη ενημερωθεί. Λύση — χρήση συνδυασμού με ETag: το ETag θα εντοπίσει την αλλαγή εντός δευτερολέπτου, ενώ το Last-Modified παραμένει ως εφεδρικό.
Το τέταρτο πρόβλημα — το Last-Modified δεν διακρίνει διαφορετικές εκδόσεις του ίδιου πόρου με ίδια ημερομηνία. Εάν ένα αρχείο έχει αποκατασταθεί από αντίγραφο ασφαλείας και το mtime του συμπίπτει με το αρχικό, ο πελάτης δεν θα παρατηρήσει ότι το περιεχόμενο έχει αλλάξει. Το ETag λύνει αυτό το πρόβλημα: το hash περιεχομένου θα αλλάξει σίγουρα με οποιαδήποτε αλλαγή δεδομένων, ανεξάρτητα από τη χρονική σήμανση. Για κρίσιμα δεδομένα, χρησιμοποιείτε πάντα και τις δύο επικεφαλίδες.
Συχνές ερωτήσεις
Μόνο GMT (Greenwich Mean Time) σε μορφή RFC 1123: ημέρα εβδομάδας, ημερομηνία, μήνας, έτος, ώρες:λεπτά:δευτερόλεπτα. Παράδειγμα: Wed, 02 Jul 2025 14:30:00 GMT. Η ζώνη ώρας είναι πάντα GMT, άλλες μορφές δεν επιτρέπονται.
Τεχνικά ναι, αλλά αυτό παραβιάζει το RFC 7232. Εάν ο διακομιστής επιστρέφει ημερομηνία στο μέλλον, οι πελάτες δεν θα ενημερώνουν τον πόρο μέχρι να φτάσει αυτή η ημερομηνία. Μια τέτοια διαμόρφωση θεωρείται σφάλμα — η ημερομηνία πρέπει να είναι στο παρελθόν ή στο παρόν.
Όχι, τα υπό αίρεση αιτήματα If-Modified-Since λειτουργούν μόνο με GET και HEAD. Τα αιτήματα POST δεν αποθηκεύονται προσωρινά και δεν χρησιμοποιούν επικύρωση βάσει ημερομηνίας. Για ελέγχους ενημερότητας δεδομένων POST, χρησιμοποιήστε ETag ή προσαρμοσμένους μηχανισμούς.
Το Cache-Control καθορίζει την πολιτική προσωρινής αποθήκευσης (μέγιστος χρόνος αποθήκευσης, ποιος μπορεί να αποθηκεύσει), ενώ το Last-Modified — τον μηχανισμό επικύρωσης της παλαιωμένης προσωρινής μνήμης. Μετά τη λήξη του max-age, ο πελάτης στέλνει If-Modified-Since για έλεγχο ενημερότητας.
Ελέγξτε ότι ο διακομιστής ορίζει πράγματι την επικεφαλίδα από την τρέχουσα πηγή — βάση δεδομένων, σύστημα αρχείων ή API. Για δυναμικές αποκρίσεις, βεβαιωθείτε ότι καλείτε ρητά res.setHeader(“Last-Modified”, ...) στον κώδικα του χειριστή.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης