Kako popraviti nedostatak CORS zaglavlja Access-Control-Allow-Origin u Express.js

Ako preglednik prikaže poruku CORS header 'Access-Control-Allow-Origin' missing, ključna naznaka nije to da Express.js nije primio zahtjev. Preglednik vam govori da odgovor nije sadržavao CORS zaglavlje koje autorizira izvor stranice da pročita taj odgovor. Stoga popravak pripada poslužitelju ili proxyju kojim upravljate, a ne nekoj nasumičnoj klijentskoj postavci.

Ilustrativni primjer korišten u ovom vodiču: zamislite nadzornu ploču zadataka koja radi na http://localhost:5173 i poziva Express API na http://localhost:3000/api/tasks. Preglednik blokira JavaScript da pročita odgovor API-ja jer API ne vraća Access-Control-Allow-Origin. Ovo je hipotetski primjer za poučavanje, a ne tvrdnja o stvarnom testu, proizvodu ili implementaciji.

Kako je provjereno 11. rujna 2026., službena dokumentacija Express CORS middlewarea navodi verziju cors 2.8.6 i opisuje je kao middleware koji postavlja CORS zaglavlja odgovora. Trenutni popis Express paketa pripada generaciji 5.x, pa ovaj vodič favorizira application-level middleware umjesto oslanjanja na starije obrasce wildcard ruta.

Što greška zapravo znači

Web stranica ima izvor (origin) sastavljen od sheme, hosta i porta. U primjeru, http://localhost:5173 i http://localhost:3000 su različiti izvori jer se njihovi portovi razlikuju. Politika istog izvora (same-origin policy) preglednika obično sprječava JavaScript na jednom izvoru da čita resurse s drugog izvora, osim ako ciljni poslužitelj ne vrati odgovarajuća zaglavlja za dijeljenje resursa između izvora (Cross-Origin Resource Sharing, CORS).

Dokumentacija MDN-a za ovu točnu grešku objašnjava da odgovoru nedostaje obavezno zaglavlje Access-Control-Allow-Origin. Ako kontrolirate poslužitelj, trebali biste konfigurirati izvor koji šalje zahtjev kao dopušteni izvor. Za javne API-je bez vjerodajnica, * može biti prikladan; za privatne API-je ili one s vjerodajnicama, koristite specifične pouzdane izvore. Pogledajte MDN-ovo objašnjenje greške s nedostatkom Access-Control-Allow-Origin.

Korak 1: Potvrdite da je CORS problem i identificirajte točan izvor

Ilustracija DevTools preglednika generirana AI-jem koja prikazuje grešku CORS-a s nedostatkom Access-Control-Allow-Origin za zahtjev s porta 5173 na localhostu prema Express API-ju na portu 3000
Ilustracija generirana AI-jem, nije stvarni snimka zaslona: preglednik prijavljuje da odgovoru Expressa nedostaje Access-Control-Allow-Origin.

Otvorite alate za razvojne programere u pregledniku i provjerite ploče Console i Network. Zabilježite izvor frontenda točno onako kako ga preglednik šalje. U našem ilustrativnom slučaju to je http://localhost:5173.

Nemojte smanjivati izvor samo na hostname. Ovo su različiti izvori: http://localhost:5173, http://localhost:3000, http://127.0.0.1:5173 i https://localhost:5173. Popis dopuštenih izvora (allowlist) u produkciji mora isto tako razlikovati https://app.example.com od drugih shema, hostova, portova ili poddomena, osim ako ih namjerno ne dopuštate.

Ako je odgovor API-ja 404, 500, preusmjeravanje, neuspjeh autentifikacije ili stranica s greškom generirana proxyjem, pregledajte i taj odgovor. CORS zaglavlja moraju biti prisutna u odgovoru koji preglednik zapravo prima. Popravak aplikacijske rute neće pomoći ako reverse proxy, CDN, balancer opterećenja ili rukovatelj greškama vrati drugačiji odgovor bez tog zaglavlja.

Korak 2: Instalirajte i učitajte službeni Express CORS middleware

Ilustracija uređivača koda generirana AI-jem koja prikazuje npm install cors naredbu i uvoz express i cors u server.js
Ilustracija generirana AI-jem, nije stvarni snimka zaslona: instalirajte cors middleware koji održava Express i učitajte ga u poslužitelj.

Za većinu Express aplikacija, najmanje sklon rješenje je cors middleware koji održava Express projekt. Službena stranica Express middlewarea navodi ga među middlewareima koje održava tim Express.js-a. Instalirajte ga u svoj API projekt:

npm install cors

Zatim ga učitajte uz Express:

const express = require('express');
const cors = require('cors');

const app = express();

Službena dokumentacija dostupna je na Express.js cors middleware dokumentaciji. Express također dokumentira kako application-level middleware izvršava redoslijedom zahtjeva na Express.js: Korištenje middlewarea.

Korak 3: Namjerno dopustite izvor frontenda

Ilustracija uređivača koda generirana AI-jem koja prikazuje app.use s cors origin postavljenim na http localhost port 5173 prije Express API rute
Ilustracija generirana AI-jem, nije stvarni snimka zaslona: konfigurirajte CORS prije API ruta kako bi dopušteni izvor primio zaglavlje odgovora.

Za hipotetsku nadzornu ploču, konfigurirajte točan razvoj izvor prije ruta kojima je potreban CORS:

const express = require('express');
const cors = require('cors');

const app = express();

const corsOptions = {
  origin: 'http://localhost:5173'
};

app.use(cors(corsOptions));
app.use(express.json());

app.get('/api/tasks', (req, res) => {
  res.json({ tasks: ['Learn Express', 'Build API'] });
});

app.listen(3000);

Postavljanje app.use(cors(corsOptions)) prije API ruta važno je jer Express obrađuje middleware redoslijedom. Middleware mora imati priliku dodati zaglavlja odgovora prije nego što ruta ili raniji middleware završi zahtjev.

Za zaista javni API koji ne koristi vjerodajnice, app.use(cors()) koristi zadano dopuštajuće ponašanje middlewarea za izvor. To je zgodno, ali ne bi trebalo biti vaš automatski izbor u produkciji. MDN preporučuje ograničavanje Access-Control-Allow-Origin na minimalne potrebne izvore i resurse. Pogledajte MDN-ove smjernice za sigurnost CORS-a.

Dopustite nekoliko poznatih izvora bez dopuštanja svima

Uobičajena produkcija ima lokalni frontend, staging frontend i produkciju frontend. Koristite allowlist i validirajte dolazni izvor:

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));

Grana !origin dopušta klijente koji ne šalju Origin zaglavlje, kao što su mnogi server-to-server zahtjevi i alati komandne linije. Želite li takvo ponašanje, odluka je politike aplikacije; CORS sam po sebi nije autentifikacija.

Korak 4: Provjerite jednostavan zahtjev i bilo koji preflight

Ilustracija Network ploče preglednika generirana AI-jem koja prikazuje OPTIONS 204 i GET 200 odgovore plus Access-Control-Allow-Origin postavljen na localhost port 5173
Ilustracija generirana AI-jem, nije stvarni snimka zaslona: provjerite prima li preglednik očekivano CORS zaglavlje i uspijeva li bilo koji OPTIONS preflight.

Ponovno učitajte frontend i pregledajte ploču Network. Uvjet uspjeha nije samo status 200. Provjerite zaglavlja odgovora. U našem ilustrativnom slučaju, odgovor API-ja trebao bi uključivati vrijednost izvora ekvivalentnu:

Access-Control-Allow-Origin: http://localhost:5173

Neki cross-origin zahtjevi pokreću preflight: preglednik šalje OPTIONS zahtjev prije stvarnog zahtjeva kako bi provjerio jesu li metoda i zaglavlja dopušteni. Zahtjevi koji koriste metode poput PUT ili DELETE, ili određena prilagođena/zaglavlja zahtjeva, obično zahtijevaju preflight. Kada je cors instaliran kao application-level middleware s app.use(cors(...)), službena Express dokumentacija kaže da se preflight zahtjevi obrađuju za sve rute.

Zaglavlja možete pregledati i izvan preglednika bez tvrdnje da klijent komandne linije provodi CORS:

curl -i   -H "Origin: http://localhost:5173"   http://localhost:3000/api/tasks

Ovo je korisno za vidjeti što poslužitelj vraća, ali uspješan curl ili zahtjev API klijenta ne dokazuje da je browser CORS ispravno konfiguriran. Expressova CORS dokumentacija izričito napominje da CORS provode preglednici; klijenti koji nisu preglednici ne primjenjuju isto ograničenje čitanja.

Zahtjevi s vjerodajnicama: nemojte kombinirati vjerodajnice s wildcard izvorom

Ako frontend mora slati kolačiće ili HTTP autentifikaciju cross-origin, obje strane trebaju kompatibilne postavke. Na Express strani, konfigurirajte specifičan pouzdan izvor i omogućite vjerodajnice:

app.use(cors({
  origin: 'https://app.example.com',
  credentials: true
}));

Na strani preglednika, fetch zahtjev koji zahtijeva kolačiće obično koristi credentials: 'include'. Nemojte mijenjati izvor poslužitelja na * za zahtjev s vjerodajnicama. Preglednici ne prihvaćaju wildcard Access-Control-Allow-Origin zajedno s CORS-om s vjerodajnicama na način na koji to programeri često očekuju, a neograničeni izvor bio bi i loša sigurnosna granica.

Zašto uobičajena „rješenja“ ne uspijevaju

PokušajZašto ne rješava stvarni problemBolji pristup
Postavite mode: 'no-cors' u fetchOdgovor postaje neproziran (opaque), pa JavaScript ne može pročitati tijelo odgovora ili većinu zaglavlja.Konfigurirajte CORS na poslužitelju kojim upravljate.
Testirajte samo u Postmanu ili curluTi klijenti ne provode politiku CORS-a preglednika.Pregledajte stvarne zaglavlja zahtjeva i odgovora u pregledniku.
Koristite Access-Control-Allow-Origin: * svugdjePotrebno je preširoko za privatne API-je i nekompatibilno s uobičajenim postavkama s vjerodajnicama.Dopustite samo pouzdane izvore kada API nije potpuno javan.
Dodajte nekoliko Access-Control-Allow-Origin zaglavljaPreglednici očekuju jednu vrijednost dopuštenog izvora, a ne više kopija ili popis izvora odvojenih zarezom.Validirajte izvor zahtjeva i vratite jednu odgovarajuću vrijednost.
Ponavljano mijenjajte kod frontendaNedostaje zaglavlje u odgovoru poslužitelja.Popravite Express ili proxy koji generira konačni odgovor.

Kada Express kod izgleda ispravno, ali greška ostaje

Ako gornja četiri koraka ne riješe grešku, pratite cijeli put zahtjeva umjesto da slijepo dodajete više zaglavlja.

  • Provjerite redoslijed middlewarea. CORS middleware bi trebao raditi prije ruta ili rukovatelja koji završavaju odgovor.
  • Provjerite preusmjeravanja. Preglednik možda prima odgovor s drugačijeg URL-a ili izvora nakon preusmjeravanja.
  • Provjerite ponašanje proxyja/CDN-a. Nginx, gateway, serverless platforma ili CDN mogu dodati, ukloniti, duplicirati ili zamijeniti zaglavlja.
  • Provjerite odgovore s greškama. Normalan 200 odgovor može sadržavati CORS zaglavlja dok 401, 404 ili 500 odgovor ne mora.
  • Provjerite doslovni izvor. Shema, hostname i port su svi važni; localhost i 127.0.0.1 nisu zamjenjivi za CORS podudaranje.
  • Provjerite duplicirana zaglavlja. MDN dokumentira da više Access-Control-Allow-Origin zaglavlja nije dopušteno. Pogledajte MDN o više Access-Control-Allow-Origin zaglavlja.

Ručna zaglavlja nasuprot cors middlewareu

CORS zaglavlja možete postaviti ručno pomoću Express API-ja za odgovore, ali lako je propustiti ponašanje preflighta, pravila vjerodajnica, dinamičko podudaranje izvora, Vary: Origin ili putanje grešaka. Službeni cors middleware već izlaže opcije za origin, metode, dopuštena zaglavlja, izložena zaglavlja, vjerodajnice, ponašanje preflighta i max age. Za većinu Express projekata, korištenje tog middlewarea održava politiku eksplicitnom i lakšom za pregled.

Ako sami implementirate logiku dinamičkog izvora, nikada ne reflektirajte svaku dolaznu Origin vrijednost automatski samo zato što je prisutna. Validirajte je protiv skupa pouzdanih izvora. MDN upozorava da neograničena cross-origin čitanja mogu izložiti podatke, posebno kada su uključene vjerodajnice.

Praktični produkcija checklist

  • Navedite točne izvore frontenda koji bi trebali moći čitati API.
  • Koristite HTTPS izvore u produkciji i držite razvojne izvore odvojenima.
  • Instalirajte CORS middleware prije zaštićenih API ruta kojima je potreban.
  • Koristite specifične izvore za privatne ili endpointe s vjerodajnicama.
  • Provjerite i normalne odgovore i preflight OPTIONS odgovore u pregledniku.
  • Provjerite putanje neuspjeha kao što su 401, 404 i 500 odgovori ako se mogu vratiti cross-origin.
  • Tretirajte CORS kao politiku čitanja preglednika, a ne kao autentifikaciju ili autorizaciju.

U ilustrativnom scenariju nadzorne ploče zadataka, trajno rješenje je jednostavno: identificirajte točan izvor frontenda, konfigurirajte Express da vrati odgovarajuće CORS zaglavlje, dopustite application-level middlewareu da obradi preflight i provjerite zaglavlja u odgovoru koji preglednik zapravo prima. Ako zaglavlje i dalje nedostaje nakon toga, sljedeći osumnjičenik obično je redoslijed middlewarea ili infrastruktura između preglednika i Expressa, a ne sam fetch poziv frontenda.

Službene reference

Ostavite komentar

Kako popraviti grešku "Tailwind CSS stilovi se ne ažuriraju" u Vite React aplikaciji

Kako popraviti grešku "Tailwind CSS stilovi se ne ažuriraju" u Vite React aplikaciji

Ispravite Tailwind CSS stilove koji se ne ažuriraju u Vite Reactu provjerom postavki Tailwind v4, CSS uvoza, otkrivanja izvora, dinamičkih klasa, HMR-a i zastarjelih predmemorija.

Kako popraviti ModuleNotFoundError: Nema modula pod nazivom 'pip' u Pythonu 3

Kako popraviti ModuleNotFoundError: Nema modula pod nazivom 'pip' u Pythonu 3

Ispravite ModuleNotFoundError u Pythonu 3 za pip na Windowsima, macOS-u i Linuxu pomoću ensurepipa, OS paketa, virtualnih okruženja i provjera interpretera.

Kako popraviti "Dozvola odbijena (javni ključ)" u GitHub SSH-u

Kako popraviti "Dozvola odbijena (javni ključ)" u GitHub SSH-u

Ispravite GitHub SSH Permission Denied (publickey) provjerom hosta, aktivnog SSH ključa, GitHub računa, SSO autorizacije, udaljenog URL-a i pristupa portu 22.

Kako popraviti "Git Push Rejected: Non-FastForward" bez gubitka promjena

Kako popraviti "Git Push Rejected: Non-FastForward" bez gubitka promjena

Sigurno ispravite Git push koji ne omogućuje brzo premotavanje. Zaštitite lokalni rad, dohvatite udaljene commitove, odaberite spajanje ili rebase, riješite sukobe i pushajte bez gubitka promjena.

Kako popraviti "Nginx 502 Bad Gateway" prilikom proxyja za Node.js

Kako popraviti "Nginx 502 Bad Gateway" prilikom proxyja za Node.js

Ispravite greške Nginx 502 Bad Gateway s Node.js uzvodno provjerom porta aplikacije, NGINX logova, proxy_pass adrese, umrežavanja kontejnera, vremenskih ograničenja i ponovnog učitavanja.

Kako popraviti "Tip 'null' se ne može dodijeliti tipu" u TypeScriptu

Kako popraviti "Tip 'null' se ne može dodijeliti tipu" u TypeScriptu

Ispravljena je greška "Tip 'null' nije moguće dodijeliti tipu" u TypeScriptu s tipovima unija, sužavanjem, zadanim vrijednostima i sigurnim tvrdnjama pod strictNullChecks.

Kako ispraviti pogrešku „Prisma Client has not been generated yet”

Kako ispraviti pogrešku „Prisma Client has not been generated yet”

Ispravite pogrešku da Prisma Client nije generiran provjerom generatora, sheme, izlazne putanje, uvoza, verzija, monorepo postavki i koraka izgradnje pri implementaciji.

Kako ispraviti "ERR_MODULE_NOT_FOUND" u Node.js ESM uvozima

Kako ispraviti "ERR_MODULE_NOT_FOUND" u Node.js ESM uvozima

Ispravite Node.js ERR_MODULE_NOT_FOUND u ESM-u provjerom putanja uvoza, ekstenzija datoteka, instalacije paketa, izvoza, ESM načina rada i čistih instalacija.

Kako riješiti problem sa SSL certifikatom: Nemoguće dobiti lokalni certifikat izdavatelja u Gitu

Kako riješiti problem sa SSL certifikatom: Nemoguće dobiti lokalni certifikat izdavatelja u Gitu

Riješite Gitovu grešku 'nemoguće dobiti lokalni certifikat izdavatelja' identificiranjem pozadine povjerenja, instaliranjem ispravnog lanca CA i održavanjem omogućene SSL verifikacije.

Kako riješiti grešku mrežnog isteka vremena MongoDB u Mongoose vezi

Kako riješiti grešku mrežnog isteka vremena MongoDB u Mongoose vezi

Riješite greške mrežnog isteka vremena MongoDB u Mongooseu identificiranjem vrste isteka, testiranjem dostupnosti Atlasa ili TCP-a, ispravljanjem URI-ja i podešavanjem vremena isteka samo kada je opravdano.