Αρχική
» ΒΑΣΙΚΕΣ ΓΝΩΣΕΙΣ
»
Πώς να διορθώσετε την έλλειψη της κεφαλίδας CORS Access-Control-Allow-Origin στο Express.js
Πώς να διορθώσετε την έλλειψη της κεφαλίδας CORS Access-Control-Allow-Origin στο Express.js
Αν ο browser εμφανίζει το μήνυμα CORS header 'Access-Control-Allow-Origin' missing, η σημαντική ένδειξη δεν είναι ότι το Express.js απέτυχε να λάβει το αίτημα. Ο browser σας ενημερώνει ότι η απόκριση δεν περιλάμβανε μια κεφαλίδα CORS που να εξουσιοδοτεί την προέλευση της σελίδας να διαβάσει αυτή την απόκριση. Επομένως, η διόρθωση πρέπει να γίνει στον διακομιστή ή σε έναν proxy που ελέγχετε εσείς, και όχι σε κάποια τυχαία ρύθμιση στην πλευρά του πελάτη.
Παραδειγματικό παράδειγμα που χρησιμοποιείται σε όλο αυτόν τον οδηγό: φανταστείτε έναν πίνακα εργασιών που εκτελείται στο http://localhost:5173 και καλεί ένα API Express στο http://localhost:3000/api/tasks. Ο browser εμποδίζει την JavaScript να διαβάσει την απόκριση του API επειδή το API δεν επιστρέφει την κεφαλίδα Access-Control-Allow-Origin. Αυτό είναι ένα υποθετικό διδακτικό παράδειγμα και όχι ισχυρισμός σχετικά με πραγματική δοκιμή, προϊόν ή ανάπτυξη.
Όπως ελέγχθηκε στις 11 Σεπτεμβρίου 2026, η επίσημη τεκμηρίωση του middleware CORS του Express αναφέρει την έκδοση 2.8.6 του cors και το περιγράφει ως middleware που ορίζει τις κεφαλίδες απόκρισης CORS. Η τρέχουσα καταγραφή του πακέτου Express ανήκει στη γενιά 5.x, γι' αυτό αυτός ο οδηγός προτιμά το middleware σε επίπεδο εφαρμογής αντί να βασίζεται σε παλαιότερα μοτίβα wildcard routes.
Τι σημαίνει πραγματικά το σφάλμα
Μια ιστοσελίδα έχει μια προέλευση (origin) που αποτελείται από το σχήμα, τον host και τη θύρα της. Στο παράδειγμα, το http://localhost:5173 και το http://localhost:3000 είναι διαφορετικές προελεύσεις επειδή οι θύρες τους διαφέρουν. Η πολιτική ίδιας προέλευσης (same-origin policy) του browser συνήθως εμποδίζει την JavaScript σε μια προέλευση να διαβάσει πόρους από μια άλλη, εκτός εάν ο διακομιστής-στόχος επιστρέφει κατάλληλες κεφαλίδες Cross-Origin Resource Sharing (CORS).
Η τεκμηρίωση του MDN για αυτό το συγκεκριμένο σφάλμα εξηγεί ότι στην απόκριση λείπει η απαιτούμενη κεφαλίδα Access-Control-Allow-Origin. Αν ελέγχετε τον διακομιστή, πρέπει να ρυθμίσετε την προέλευση του αιτούμενου ιστότοπου ως επιτρεπόμενη προέλευση. Για δημόσια APIs χωρίς διαπιστευτήρια, το * μπορεί να είναι κατάλληλο· για ιδιωτικά ή APIs με διαπιστευτήρια, χρησιμοποιήστε συγκεκριμένες έμπιστες προελεύσεις. Δείτε την εξήγηση του MDN για το σφάλμα έλλειψης Access-Control-Allow-Origin.
Βήμα 1: Επιβεβαιώστε ότι το CORS είναι το πρόβλημα και εντοπίστε την ακριβή προέλευση
Εικόνα δημιουργημένη από AI, όχι πραγματικό στιγμιότυπο οθόνης: ο browser αναφέρει ότι στην απόκριση του Express λείπει η Access-Control-Allow-Origin.
Ανοίξτε τα εργαλεία προγραμματιστή του browser και ελέγξτε τόσο το πάνελ Console όσο και το πάνελ Network. Καταγράψτε την προέλευση του frontend ακριβώς όπως τη στέλνει ο browser. Στην περίπτωσή μας, είναι το http://localhost:5173.
Μην αναγάγετε μια προέλευση απλώς σε ένα hostname. Αυτές είναι διαφορετικές προελεύσεις: http://localhost:5173, http://localhost:3000, http://127.0.0.1:5173 και https://localhost:5173. Μια λίστα επιτρεπόμενων (allowlist) σε παραγωγικό περιβάλλον πρέπει επίσης να διακρίνει το https://app.example.com από άλλα σχήματα, hosts, θύρες ή υποτομείς, εκτός εάν τους επιτρέπετε σκόπιμα.
Αν η απόκριση του API είναι 404, 500, ανακατεύθυνση, αποτυχία ελέγχου ταυτότητας ή σελίδα σφάλματος παραγόμενη από proxy, ελέγξτε επίσης αυτή την απόκριση. Οι κεφαλίδες CORS πρέπει να υπάρχουν στην απόκριση που λαμβάνει πραγματικά ο browser. Η διόρθωση μιας διαδρομής της εφαρμογής δεν θα βοηθήσει αν ένας reverse proxy, CDN, load balancer ή χειριστής σφαλμάτων επιστρέφει μια διαφορετική απόκριση χωρίς την κεφαλίδα.
Βήμα 2: Εγκαταστήστε και φορτώστε το επίσημο middleware CORS του Express
Εικόνα δημιουργημένη από AI, όχι πραγματικό στιγμιότυπο οθόνης: εγκαταστήστε το middleware cors που συντηρείται από το Express και φορτώστε το στον διακομιστή.
Για τις περισσότερες εφαρμογές Express, η λύση με τη μικρότερη πιθανότητα σφάλματος είναι το middleware cors που συντηρείται από το έργο Express. Η επίσημη σελίδα middleware του Express το αναφέρει μεταξύ των middleware που συντηρούνται από την ομάδα του Express.js. Εγκαταστήστε το στο έργο του API σας:
Βήμα 3: Επιτρέψτε σκόπιμα την προέλευση του frontend
Εικόνα δημιουργημένη από AI, όχι πραγματικό στιγμιότυπο οθόνης: ρυθμίστε το CORS πριν από τις διαδρομές του API ώστε η επιτρεπόμενη προέλευση να λαμβάνει την κεφαλίδα απόκρισης.
Για τον υποθετικό πίνακα εργασιών, ρυθμίστε την ακριβή προέλευση ανάπτυξης πριν από τις διαδρομές που χρειάζονται CORS:
Η τοποθέτηση του app.use(cors(corsOptions)) πριν από τις διαδρομές του API είναι σημαντική επειδή το Express επεξεργάζεται το middleware με τη σειρά. Το middleware χρειάζεται την ευκαιρία να προσθέσει κεφαλίδες απόκρισης πριν μια διαδρομή ή προηγούμενο middleware τερματίσει το αίτημα.
Για ένα πραγματικά δημόσιο API που δεν χρησιμοποιεί διαπιστευτήρια, το app.use(cors()) χρησιμοποιεί την προεπιλεγμένη επιτρεπτική συμπεριφορά προέλευσης του middleware. Αυτό είναι βολικό, αλλά δεν πρέπει να είναι η αυτόματη επιλογή σας σε παραγωγικό περιβάλλον. Το MDN συνιστά τον περιορισμό του Access-Control-Allow-Origin στις ελάχιστες απαιτούμενες προελεύσεις και πόρους. Δείτε τις οδηγίες ασφαλείας CORS του MDN.
Επιτρέψτε πολλές γνωστές προελεύσεις χωρίς να επιτρέψετε σε όλους
Μια συνηθισμένη ρύθμιση σε παραγωγικό περιβάλλον έχει ένα τοπικό frontend, ένα staging frontend και ένα παραγωγικό frontend. Χρησιμοποιήστε μια λίστα επιτρεπόμενων και επικυρώστε την εισερχόμενη προέλευση:
const allowedOrigins = new Set([
'http://localhost:5173',
'https://staging.example.com',
'https://app.example.com'
]);
const corsOptions = {
origin(origin, callback) {
if (!origin || allowedOrigins.has(origin)) {
callback(null, true);
return;
}
callback(new Error('Origin not allowed by CORS'));
}
};
app.use(cors(corsOptions));
Ο κλάδος !origin επιτρέπει σε πελάτες που δεν στέλνουν κεφαλίδα Origin, όπως πολλά αιτήματα server-to-server και εργαλεία γραμμής εντολών. Το αν θέλετε αυτή τη συμπεριφορά είναι απόφαση πολιτικής της εφαρμογής· το CORS καθαυτό δεν είναι έλεγχος ταυτότητας.
Βήμα 4: Επαληθεύστε το απλό αίτημα και οποιοδήποτε preflight
Εικόνα δημιουργημένη από AI, όχι πραγματικό στιγμιότυπο οθόνης: επαληθεύστε ότι ο browser λαμβάνει την αναμενόμενη κεφαλίδα CORS και ότι οποιοδήποτε OPTIONS preflight πετυχαίνει.
Φορτώστε ξανά το frontend και επιθεωρήστε το πάνελ Network. Η συνθήκη επιτυχίας δεν είναι απλώς μια κατάσταση 200. Ελέγξτε τις κεφαλίδες απόκρισης. Στην περίπτωσή μας, η απόκριση του API πρέπει να περιλαμβάνει μια τιμή προέλευσης ισοδύναμη με:
Ορισμένα cross-origin αιτήματα πυροδοτούν ένα preflight: ο browser στέλνει ένα αίτημα OPTIONS πριν από το πραγματικό αίτημα για να ελέγξει αν η μέθοδος και οι κεφαλίδες επιτρέπονται. Αιτήματα που χρησιμοποιούν μεθόδους όπως PUT ή DELETE, ή ορισμένες προσαρμοσμένες/αιτούμενες κεφαλίδες, συνήθως χρειάζονται preflight. Όταν το cors είναι εγκατεστημένο ως middleware σε επίπεδο εφαρμογής με app.use(cors(...)), η επίσημη τεκμηρίωση του Express αναφέρει ότι τα αιτήματα preflight διαχειρίζονται για όλες τις διαδρομές.
Μπορείτε επίσης να επιθεωρήσετε τις κεφαλίδες εκτός browser χωρίς να ισχυριστείτε ότι ο πελάτης γραμμής εντολών επιβάλλει το CORS:
Αυτό είναι χρήσιμο για να δείτε τι επιστρέφει ο διακομιστής, αλλά μια επιτυχής αίτηση curl ή API-client δεν αποδεικνύει ότι το CORS του browser είναι ρυθμισμένο σωστά. Η τεκμηρίωση CORS του Express σημειώνει ρητά ότι το CORS επιβάλλεται από τους browser· οι πελάτες που δεν είναι browser δεν εφαρμόζουν τον ίδιο περιορισμό ανάγνωσης.
Αιτήματα με διαπιστευτήρια: μην συνδυάζετε διαπιστευτήρια με wildcard προέλευση
Αν το frontend πρέπει να στέλνει cookies ή έλεγχο ταυτότητας HTTP cross-origin, και οι δύο πλευρές χρειάζονται συμβατές ρυθμίσεις. Στην πλευρά του Express, ρυθμίστε μια συγκεκριμένη έμπιστη προέλευση και ενεργοποιήστε τα διαπιστευτήρια:
Στην πλευρά του browser, ένα αίτημα fetch που χρειάζεται cookies χρησιμοποιεί συνήθως credentials: 'include'. Μην αλλάξετε την προέλευση του διακομιστή σε * για ένα αίτημα με διαπιστευτήρια. Οι browser δεν δέχονται μια wildcard Access-Control-Allow-Origin μαζί με CORS με διαπιστευτήρια με τον τρόπο που συχνά περιμένουν οι προγραμματιστές, και μια μη περιορισμένη προέλευση θα ήταν επίσης κακό όριο ασφαλείας.
Γιατί οι κοινές «διορθώσεις» αποτυγχάνουν
Προσπάθεια
Γιατί δεν λύνει το πραγματικό πρόβλημα
Καλύτερη προσέγγιση
Ορίστε mode: 'no-cors' στο fetch
Η απόκριση γίνεται αδιαφανής (opaque), οπότε η JavaScript δεν μπορεί να διαβάσει το σώμα της απόκρισης ή τις περισσότερες κεφαλίδες.
Ρυθμίστε το CORS στον διακομιστή που ελέγχετε εσείς.
Δοκιμάστε μόνο στο Postman ή curl
Αυτοί οι πελάτες δεν επιβάλλουν την πολιτική CORS του browser.
Επιθεωρήστε τα πραγματικά headers αιτήματος και απόκρισης του browser.
Είναι περιττά ευρύ για ιδιωτικά APIs και ασύμβατο με κοινές ρυθμίσεις με διαπιστευτήρια.
Επιτρέψτε μόνο έμπιστες προελεύσεις όταν το API δεν είναι πλήρως δημόσιο.
Προσθέστε πολλές κεφαλίδες Access-Control-Allow-Origin
Οι browser αναμένουν μια μοναδική τιμή επιτρεπόμενης προέλευσης, όχι πολλαπλά αντίγραφα ή λίστα προελεύσεων χωρισμένη με κόμμα.
Επικυρώστε την προέλευση του αιτήματος και επιστρέψτε μία ταιριαστή τιμή.
Αλλάζετε επανειλημμένα τον κώδικα του frontend
Η κεφαλίδα που λείπει βρίσκεται στην απόκριση του διακομιστή.
Διορθώστε το Express ή τον proxy που παράγει την τελική απόκριση.
Όταν ο κώδικας Express φαίνεται σωστός αλλά το σφάλμα παραμένει
Αν τα τέσσερα παραπάνω βήματα δεν επιλύσουν το σφάλμα, ιχνηλατήστε ολόκληρη τη διαδρομή του αιτήματος αντί να προσθέτετε τυφλά περισσότερες κεφαλίδες.
Ελέγξτε τη σειρά του middleware. Το middleware CORS πρέπει να εκτελείται πριν από διαδρομές ή χειριστές που τερματίζουν την απόκριση.
Ελέγξτε τις ανακατευθύνσεις. Ο browser μπορεί να λαμβάνει απόκριση από διαφορετικό URL ή προέλευση μετά από μια ανακατεύθυνση.
Ελέγξτε τη συμπεριφορά proxy/CDN. Το Nginx, μια πύλη (gateway), μια πλατφόρμα serverless ή ένα CDN μπορούν να προσθέσουν, αφαιρέσουν, διπλασιάσουν ή αντικαταστήσουν κεφαλίδες.
Ελέγξτε τις αποκρίσεις σφαλμάτων. Μια κανονική απόκριση 200 μπορεί να περιέχει κεφαλίδες CORS ενώ μια απόκριση 401, 404 ή 500 όχι.
Ελέγξτε την κυριολεκτική προέλευση. Το σχήμα, το hostname και η θύρα έχουν σημασία· το localhost και το 127.0.0.1 δεν είναι εναλλάξιμα για την αντιστοίχιση CORS.
Μπορείτε να ορίσετε κεφαλίδες CORS χειροκίνητα με τα APIs απόκρισης του Express, αλλά είναι εύκολο να παραλείψετε τη συμπεριφορά preflight, τους κανόνες διαπιστευτηρίων, την δυναμική αντιστοίχιση προέλευσης, το Vary: Origin ή τα μονοπάτια σφαλμάτων. Το επίσημο middleware cors εκθέτει ήδη επιλογές για origin, μεθόδους, επιτρεπόμενες κεφαλίδες, εκτεθειμένες κεφαλίδες, διαπιστευτήρια, συμπεριφορά preflight και max age. Για τα περισσότερα έργα Express, η χρήση αυτού του middleware κρατά την πολιτική ρητή και ευκολότερη στην επιθεώρηση.
Αν υλοποιήσετε μόνοι σας δυναμική λογική προέλευσης, μην αντανακλάτε ποτέ αυτόματα κάθε εισερχόμενη τιμή Origin μόνο επειδή υπάρχει. Επικυρώστε την έναντι ενός έμπιστου συνόλου. Το MDN προειδοποιεί ότι οι μη περιορισμένες cross-origin αναγνώσεις μπορούν να εκθέσουν δεδομένα, ιδιαίτερα όταν εμπλέκονται διαπιστευτήρια.
Ένα πρακτικό checklist παραγωγής
Καταγράψτε τις ακριβείς προελεύσεις frontend που πρέπει να μπορούν να διαβάσουν το API.
Χρησιμοποιήστε προελεύσεις HTTPS σε παραγωγικό περιβάλλον και κρατήστε τις προελεύσεις ανάπτυξης ξεχωριστά.
Εγκαταστήστε το middleware CORS πριν από προστατευόμενες διαδρομές API που το χρειάζονται.
Χρησιμοποιήστε συγκεκριμένες προελεύσεις για ιδιωτικά ή endpoints με διαπιστευτήρια.
Επαληθεύστε τόσο τις κανονικές αποκρίσεις όσο και τις αποκρίσεις preflight OPTIONS στον browser.
Επαληθεύστε τα μονοπάτια αποτυχίας όπως οι αποκρίσεις 401, 404 και 500 αν μπορούν να επιστραφούν cross-origin.
Θεωρήστε το CORS ως πολιτική ανάγνωσης του browser, όχι ως έλεγχο ταυτότητας ή εξουσιοδότησης.
Στο παραδειγματικό σενάριο του πίνακα εργασιών, η μόνιμη διόρθωση είναι απλή: εντοπίστε την ακριβή προέλευση του frontend, ρυθμίστε το Express να επιστρέφει την ταιριαστή κεφαλίδα CORS, αφήστε το middleware σε επίπεδο εφαρμογής να διαχειριστεί το preflight και επαληθεύστε τις κεφαλίδες στην απόκριση που λαμβάνει πραγματικά ο browser. Αν η κεφαλίδα λείπει ακόμα μετά από αυτό, ο επόμενος ύποπτος είναι συνήθως η σειρά του middleware ή η υποδομή μεταξύ του browser και του Express, και όχι η ίδια η κλήση fetch του frontend.