Last-Modified — ουσία, μηχανισμός και ρύθμιση επικεφαλίδας ημερομηνίας τροποποίησης

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-03-09 Χρόνος ανάγνωσης: 9 λεπ

Last-Modified — HTTP επικεφαλίδα απόκρισης που υποδεικνύει την ημερομηνία και ώρα της τελευταίας τροποποίησης ενός πόρου στον διακομιστή, επιτρέποντας στον πελάτη να εκτελεί υπό αίρεση αιτήματα μέσω του If-Modified-Since. Εάν ο πόρος δεν έχει αλλάξει από την αναφερόμενη ημερομηνία, ο διακομιστής επιστρέφει 304 Not Modified χωρίς μετάδοση σώματος απόκρισης, εξοικονομώντας σημαντικά εύρος ζώνης. Σύμφωνα με το RFC 7232 (IETF, 2014), τα υπό αίρεση αιτήματα με Last-Modified μειώνουν τον χρόνο φόρτωσης σελίδων κατά 30-60% σε επαναλαμβανόμενες επισκέψεις. Η επικεφαλίδα υποστηρίζεται αυτόματα από τους περισσότερους HTTP διακομιστές και διακομιστές μεσολάβησης.

Βασικά σημεία

  • Last-Modified — HTTP επικεφαλίδα με ημερομηνία τελευταίας τροποποίησης πόρου για υπό αίρεση αιτήματα If-Modified-Since
  • 304 Not Modified — απόκριση διακομιστή εάν ο πόρος δεν έχει αλλάξει· ο πελάτης χρησιμοποιεί το αποθηκευμένο αντίγραφό του
  • Ακρίβεια δευτερολέπτου — περιορισμός της επικεφαλίδας: αλλαγές εντός ενός δευτερολέπτου μπορεί να περάσουν απαρατήρητες
  • Συνεργασία με ETag — ο διακομιστής επιστρέφει και τις δύο επικεφαλίδες, ο πελάτης στέλνει και τα δύο υπό αίρεση αιτήματα
  • Αυτόματη δημιουργία — οι Nginx και Apache ορίζουν το Last-Modified για στατικά αρχεία από το σύστημα αρχείων

Τι είναι το Last-Modified;

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

Η επικεφαλίδα Last-Modified ορίστηκε ήδη στο HTTP/1.0 (RFC 1945, 1996) και έγινε ένας από τους πρώτους μηχανισμούς διαχείρισης προσωρινής αποθήκευσης στον ιστό. Πριν από την εμφάνιση του ETag στο HTTP/1.1, ήταν ο μοναδικός τρόπος εκτέλεσης υπό αίρεση αιτημάτων. Παρά την ηλικία της, η επικεφαλίδα παραμένει επίκαιρη χάρη στην απλότητά της — ο διακομιστής δεν χρειάζεται να υπολογίσει hash περιεχομένου, αρκεί να διαβάσει το timestamp αρχείου από το σύστημα αρχείων ή το πεδίο updated_at από τη βάση δεδομένων.

Πώς λειτουργεί το Last-Modified;

Ο πλήρης κύκλος περιλαμβάνει τρία στάδια. Στο πρώτο αίτημα, ο διακομιστής επιστρέφει τον πόρο με την επικεφαλίδα Last-Modified και HTTP κατάσταση 200 OK. Ο πελάτης αποθηκεύει προσωρινά την απόκριση μαζί με την ημερομηνία. Σε επαναλαμβανόμενο αίτημα, ο πελάτης στέλνει την επικεφαλίδα If-Modified-Since με την αποθηκευμένη ημερομηνία. Ο διακομιστής συγκρίνει αυτήν την ημερομηνία με τον τρέχοντα χρόνο τροποποίησης του πόρου. Εάν ο πόρος δεν έχει τροποποιηθεί — επιστρέφεται 304 Not Modified με κενό σώμα. Εάν έχει τροποποιηθεί — 200 OK με νέα δεδομένα και νέο Last-Modified.

http
// Πρώτο αίτημα — ο διακομιστής επιστρέφει τον πόρο με ημερομηνία
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 vs ETag

Το Last-Modified και το ETag εκτελούν παρόμοια εργασία — επιτρέπουν στον πελάτη να ελέγξει την ενημερότητα της προσωρινής μνήμης — αλλά έχουν θεμελιώδεις διαφορές. Το Last-Modified χρησιμοποιεί χρονική σήμανση, το ETag — μοναδικό αναγνωριστικό έκδοσης. Κάθε προσέγγιση έχει τα σενάριά της όπου είναι πιο αποτελεσματική και η σύσταση της προδιαγραφής HTTP είναι να χρησιμοποιούνται και οι δύο επικεφαλίδες μαζί.

ΚριτήριοLast-ModifiedETag
ΟυσίαΗμερομηνία τελευταίας τροποποίησηςΜοναδικό αναγνωριστικό έκδοσης
ΑκρίβειαΜέχρι δευτερόλεπτοΜέχρι 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 στον διακομιστή

Η ρύθμιση του Last-Modified εξαρτάται από τον τύπο διακομιστή. Για Nginx και Apache, το Last-Modified ορίζεται αυτόματα για στατικά αρχεία βάσει mtime. Για δυναμικές εφαρμογές, η επικεφαλίδα πρέπει να ορίζεται στον κώδικα του διακομιστή. Ας δούμε τη ρύθμιση σε δημοφιλείς πλατφόρμες.

javascript
// 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

Ο 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 περιεχομένου θα αλλάξει σίγουρα με οποιαδήποτε αλλαγή δεδομένων, ανεξάρτητα από τη χρονική σήμανση. Για κρίσιμα δεδομένα, χρησιμοποιείτε πάντα και τις δύο επικεφαλίδες.

  • Ακρίβεια δευτερολέπτου — δεν ανιχνεύει αλλαγές εντός ενός δευτερολέπτου· χρησιμοποιήστε ETag για ενημερώσεις υψηλής συχνότητας
  • Συσταδοποίηση — το mtime μπορεί να διαφέρει σε διαφορετικούς διακομιστές· συγχρονίστε μέσω NTP ή χρησιμοποιήστε ETag
  • Race condition — εάν ο πόρος άλλαξε μετά την αποστολή If-Modified-Since αλλά πριν από τον έλεγχο στον διακομιστή
  • Παρερμηνεία διακομιστή μεσολάβησης — ορισμένοι διακομιστές μεσολάβησης μπορεί να αλλάξουν το Last-Modified κατά την προσωρινή αποθήκευση· το HTTPS λύνει αυτό το πρόβλημα

Συχνές ερωτήσεις

Ποια μορφή ημερομηνίας χρησιμοποιείται στο Last-Modified;

Μόνο GMT (Greenwich Mean Time) σε μορφή RFC 1123: ημέρα εβδομάδας, ημερομηνία, μήνας, έτος, ώρες:λεπτά:δευτερόλεπτα. Παράδειγμα: Wed, 02 Jul 2025 14:30:00 GMT. Η ζώνη ώρας είναι πάντα GMT, άλλες μορφές δεν επιτρέπονται.

Μπορεί το Last-Modified να είναι στο μέλλον;

Τεχνικά ναι, αλλά αυτό παραβιάζει το RFC 7232. Εάν ο διακομιστής επιστρέφει ημερομηνία στο μέλλον, οι πελάτες δεν θα ενημερώνουν τον πόρο μέχρι να φτάσει αυτή η ημερομηνία. Μια τέτοια διαμόρφωση θεωρείται σφάλμα — η ημερομηνία πρέπει να είναι στο παρελθόν ή στο παρόν.

Το Last-Modified λειτουργεί με αιτήματα POST;

Όχι, τα υπό αίρεση αιτήματα If-Modified-Since λειτουργούν μόνο με GET και HEAD. Τα αιτήματα POST δεν αποθηκεύονται προσωρινά και δεν χρησιμοποιούν επικύρωση βάσει ημερομηνίας. Για ελέγχους ενημερότητας δεδομένων POST, χρησιμοποιήστε ETag ή προσαρμοσμένους μηχανισμούς.

Πώς αλληλεπιδρά το Last-Modified με το Cache-Control;

Το Cache-Control καθορίζει την πολιτική προσωρινής αποθήκευσης (μέγιστος χρόνος αποθήκευσης, ποιος μπορεί να αποθηκεύσει), ενώ το Last-Modified — τον μηχανισμό επικύρωσης της παλαιωμένης προσωρινής μνήμης. Μετά τη λήξη του max-age, ο πελάτης στέλνει If-Modified-Since για έλεγχο ενημερότητας.

Τι να κάνω εάν το Last-Modified δεν αλλάζει κατά την ενημέρωση δεδομένων;

Ελέγξτε ότι ο διακομιστής ορίζει πράγματι την επικεφαλίδα από την τρέχουσα πηγή — βάση δεδομένων, σύστημα αρχείων ή API. Για δυναμικές αποκρίσεις, βεβαιωθείτε ότι καλείτε ρητά res.setHeader(“Last-Modified”, ...) στον κώδικα του χειριστή.

Σύνοψη

  • Last-Modified — HTTP επικεφαλίδα με ημερομηνία τελευταίας τροποποίησης πόρου για υπό αίρεση αιτήματα 304
  • Απλότητα υλοποίησης — λειτουργεί αυτόματα για στατικά (mtime αρχείου) και απαιτεί ελάχιστο κώδικα για API
  • Ακρίβεια δευτερολέπτου — κύριος περιορισμός· για αλλαγές υψηλής συχνότητας χρησιμοποιήστε ETag
  • ETag ακριβέστερο, Last-Modified απλούστερο — βέλτιστος συνδυασμός: και οι δύο επικεφαλίδες μαζί
  • HTTP μορφή ημερομηνίας — μόνο GMT, RFC 1123, σταθερό μήκος 29 χαρακτήρων
  • Συσταδοποίηση — απαιτεί συγχρονισμό ώρας (NTP) ή χρήση ETag ως κύριου μηχανισμού
  • Σύσταση — να προσθέτετε πάντα Last-Modified για API και να το ενεργοποιείτε για στατικά μέσω Nginx/Apache

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης