Vodiči

Kako popraviti CORS greške (i zašto se javljaju)

CORS greška znači da je vaša web stranica pokušala da pročita odgovor s drugog izvora (drugog domena, porta ili protokola), a taj server nije poslao zaglavlja koja kažu da je to dozvoljeno. Pregledači blokiraju odgovor radi zaštite korisnika. Popravljate to na serveru, vraćanjem zaglavlja Access-Control-Allow-Origin za izvor vašeg sajta i obradom OPTIONS preflight zahtjeva, ili to izbjegavate slanjem zahtjeva kroz vlastiti backend na istom izvoru.

Riječ je o jednoj od najzbunjujućih grešaka u web razvoju, jer zahtjev često uspješno stiže do servera. Ovaj vodič objašnjava šta se dešava i kako popraviti svaku varijantu.

Šta znači „izvor”

Izvor je kombinacija protokola, domena i porta:

URLIzvor
https://myapp.com/dashboardhttps://myapp.com
https://api.myapp.com/usershttps://api.myapp.com (drugi poddomen, pa drugi izvor)
http://localhost:5173http://localhost:5173
http://localhost:3000http://localhost:3000 (drugi port, pa drugi izvor)

Pregledači slijede politiku istog izvora: JavaScript na stranici može slobodno čitati odgovore sa svog izvora, ali ne i s drugih. CORS (Cross-Origin Resource Sharing) je sistem koji serveru omogućava da se uključi: „odgovore sa mene mogu čitati stranice s ovih izvora.”

Dvije posljedice iznenađuju ljude:

  • Zahtjev često stigne do servera. CORS obično blokira vaš kod da pročita odgovor, a ne server da primi zahtjev. POST može biti sačuvan iako ste vidjeli grešku.
  • Samo pregledači ga primjenjuju. curl, Postman i kod na serverskoj strani potpuno ignorišu CORS. Zato to što „radi u Postmanu” ne govori ništa o CORS-u.

Korak 1: Pročitajte tačnu grešku

Otvorite alate za developere (desni klik → Inspect), idite na Console i pročitajte cijelu poruku. Chromeova formulacija pokazuje koji problem imate:

Poruka sadržiŠta nije u redu
No 'Access-Control-Allow-Origin' header is presentServer uopšte nije poslao zaglavlje ili je zahtjev pao prije nego što je stigao do vašeg CORS koda (na primjer 404 ili 500)
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied originServer dozvoljava drugi izvor, a ne vaš
Response to preflight request doesn't pass access control checkOPTIONS preflight nije prošao
...must not be the wildcard '*' when the request's credentials mode is 'include'Šaljete kolačiće, a server je odgovorio sa *
Request header field authorization is not allowedServer nije naveo to zaglavlje u Access-Control-Allow-Headers

Zatim otvorite karticu Network, pronađite neuspješni zahtjev (i eventualni OPTIONS zahtjev prije njega) i pogledajte njegov statusni kod i zaglavlja odgovora.

Prvo provjerite statusni kod. Mnoge „CORS greške” su zapravo greška servera u prerušenju. Ako server padne ili vrati 404, njegov odgovor o grešci često nema CORS zaglavlja, pa pregledač prijavljuje CORS umjesto pravog problema. Popravite 500 ili 404, i CORS greška može nestati.

Korak 2: Odlučite treba li uopšte zvati taj API iz pregledača

Prije dodavanja zaglavlja pitajte se: treba li pregledač direktno zvati ovaj API?

  • API treće strane koji traži tajni ključ (OpenAI, Stripe tajni ključ, većina servisa za e-poštu) nikada ne smije biti pozivan iz pregledača. Ključ bi bio vidljiv svakom posjetiocu. Pozovite ga iz svog backenda, a CORS problem nestaje, jer se zahtjevi server-na-server ne podvrgavaju CORS-u. Pogledajte kako čuvati API ključeve.
  • API treće strane koji ne kontrolišete i koji ne šalje CORS zaglavlja ne može se popraviti s vaše strane. Pozovite ga iz svog backenda.
  • Vlastiti API može se popraviti pravilnom konfiguracijom. Nastavite ispod.

Korak 3: Popravite na svom serveru

Server mora dodati ispravna zaglavlja svojim odgovorima, uključujući odgovore o greškama.

Za stvarni zahtjev pošaljite:

  • Access-Control-Allow-Origin: https://myapp.com (tačan izvor vašeg front enda, bez završne kose crte)
  • Vary: Origin, ako vrijednost zavisi od toga koji izvor je tražio

Za preflight OPTIONS zahtjev odgovorite statusom uspjeha (200 ili 204) i:

  • Access-Control-Allow-Origin: https://myapp.com
  • Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
  • Access-Control-Allow-Headers: Content-Type, Authorization (svako prilagođeno zaglavlje koje šaljete)
  • Opciono Access-Control-Max-Age: 600, da pregledač keširati preflight neko vrijeme

Većina okvira ima paket ili postavku koja to radi. U Expressu je to paket cors; u FastAPI-ju CORSMiddleware; u ASP.NET Core-u AddCors; u Springu @CrossOrigin ili CORS konfiguracija. Tipična Express postavka:

import cors from "cors";

app.use(cors({
  origin: ["https://myapp.com", "http://localhost:5173"],
  credentials: true,
}));

Stavite CORS obradu prije svojih ruta i autentifikacije, da preflight zahtjevi (koji ne nose prijavu) ne budu odbijeni s 401.

S AI alatom opišite postavku precizno:

Front end na https://myapp.com poziva API na https://api.myapp.com i dobija „Response to preflight request doesn't pass access control check”. Konfiguriši CORS na API-ju tako da dozvoljava tačno https://myapp.com i izvor preview-a, dozvoli GET, POST, PATCH, DELETE sa zaglavljima Content-Type i Authorization, obradi OPTIONS prije autentifikacije i uključi CORS zaglavlja i u odgovore o greškama.

Korak 4: Obradite kolačiće i kredencijale

Ako vaš front end šalje kolačiće (na primjer sesiju prijave) drugom izvoru, obje strane se moraju složiti:

  • Front end postavlja credentials: "include" na fetch, ili withCredentials: true u axiosu.
  • Server šalje Access-Control-Allow-Credentials: true.
  • Access-Control-Allow-Origin na serveru mora biti tačan izvor, a ne *.

Kolačići između različitih sajtova također trebaju SameSite=None; Secure na kolačiću, a neki pregledači dodatno ograničavaju kolačiće trećih strana. To je još jedan razlog da se radije odlučite za pristup iz Koraka 5.

Korak 5: Izbjegnite CORS pomoću postavke istog izvora

Često je najčistije rješenje da uopšte ne pravite zahtjeve između različitih izvora. Servirajte API s istog izvora kao stranicu, na primjer na https://myapp.com/api/...:

  • U razvoju, većina razvojnih servera može raditi kao proxy. Postavka server.proxy u Vite-u može proslijediti /api vašem backendu na drugom portu, pa pregledač uvijek komunicira s jednim izvorom.
  • U produkciji, prosljeđujte /api backendu kroz postavke rewrite-a ili proxyja vašeg hosta, ili servirajte front end i API s jednog servera.

Front end tada poziva relativnu putanju poput fetch("/api/orders"). Nema zahtjeva između različitih izvora, nema preflighta između izvora i nema problema s kolačićima. Također znači da ne morate hard-kodirati domen API-ja koji se razlikuje između preview-a i produkcije.

Promijeni front end da poziva backend preko relativnih /api putanja umjesto punog URL-a i postavi dev proxy tako da /api ide na API server. Zatim ukloni CORS postavke koje više nisu potrebne.

Šta ne raditi

  • mode: "no-cors" u fetch-u. Ništa ne zaobilazi; vašem kodu daje prazan, nečitljiv odgovor.
  • Dodaci za pregledač koji isključuju CORS. Mijenjaju samo vaš pregledač. Svaki posjetilac i dalje vidi grešku.
  • Javni „CORS proxy” servisi za prave aplikacije. Mogu čitati i mijenjati sve što prolazi kroz njih, a i sami znaju da padnu.
  • Access-Control-Allow-Origin: * na API-ju koji koristi prijave. Ionako ne radi s kredencijalima i pogrešan je podrazumijevani izbor za privatne podatke.
  • Vraćanje bilo kojeg Origin zaglavlja nazad uz dozvoljene kredencijale. To omogućava bilo kojem sajtu da šalje zahtjeve u ime vaših prijavljenih korisnika. Koristite listu dozvoljenih.

Česti uzroci u aplikacijama napravljenim uz AI

SituacijaRješenje
Front end poziva API treće strane s tajnim ključemPremjestite poziv na backend
Radi u preview-u, ne radi na objavljenom domenuDodajte objavljeni izvor i izvor prilagođenog domena na listu dozvoljenih ili koristite relativne /api putanje
Greška samo na POST, PUT ili DELETEPreflight nije obrađen; dodajte obradu OPTIONS i dozvoljena zaglavlja
Greška se pojavila nakon dodavanja prijaveKredencijalima treba tačan izvor i Allow-Credentials
„CORS greška”, ali karticu Network pokazuje 500Prvo popravite grešku servera
URL API-ja hard-kodiran na localhostKoristite relativne putanje ili postavku po okruženju

CORS u Mythexu

Kada Mythex projekat ima web sajt i API server, oba rade kao servisi u istom projektu i možete prelaziti s jednog na drugi u preview-u. Ako zamolite agenta da front end poziva backend kroz relativnu /api putanju, proksirano u razvoju, izbjegavate većinu CORS problema. Ako ipak trebate pozive između različitih izvora, dajte agentu tačnu grešku iz konzole i uključene izvore. Provjerite rezultat i na objavljenoj aplikaciji, jer se njena adresa razlikuje od preview-a. Pogledajte Aplikacije s više servisa i API backendi u dokumentaciji, kao i naše vodiče o otklanjanju grešaka u aplikaciji napravljenoj uz AI i frontend naspram backenda.

Kontrolna lista za CORS

  • Pročitana cijela greška iz konzole i statusni kod neuspjelog zahtjeva
  • Isključen skriveni 404 ili 500
  • API-ji s tajnim ključevima pozivaju se s backenda, a ne iz pregledača
  • Server šalje Access-Control-Allow-Origin s tačnim dozvoljenim izvorima
  • OPTIONS preflight odgovoren dozvoljenim metodama i zaglavljima, prije autentifikacije
  • CORS zaglavlja prisutna i u odgovorima o greškama
  • Kredencijali: tačan izvor, Allow-Credentials: true, ispravne postavke kolačića
  • Pokriveni izvori preview-a, objavljene aplikacije i prilagođenog domena, ili korištene relativne /api putanje
  • Nema no-cors, javnih proxyja ili prečica koje vraćaju bilo koji izvor

Pitanja

Šta znači CORS greška?

Vaša stranica, učitana iz jednog izvora, pokušala je da pročita odgovor s drugog izvora, a odgovor tog servera nije sadržao zaglavlja koja to dozvoljavaju. Pregledač blokira vaš kod da pročita odgovor. Rješenje je na serveru ili u tome kako se zahtjev rutira, a ne u frontend kodu.

Mogu li popraviti CORS grešku s frontenda?

Ne na pravi način. Postavke poput mode: 'no-cors' samo sakrivaju odgovor od vašeg koda. Popravljate tako što server šalje ispravno zaglavlje Access-Control-Allow-Origin ili tako što API poziva iz vašeg backenda ili preko proxyja istog izvora.

Da li je Access-Control-Allow-Origin: * sigurno?

U redu je za javne podatke koje svako može čitati, poput javnog API-ja bez prijave. Ne može se koristiti s kolačićima ni drugim kredencijalima, a za privatne API-je treba navesti tačne dozvoljene izvore.

Zašto moj zahtjev radi u Postmanu ili curlu, ali ne u pregledaču?

CORS primjenjuju samo pregledači. Alati poput Postmana i curla ga ne primjenjuju, pa zahtjev tamo može uspjeti, a da bude blokiran kada ga pokrene JavaScript stranice.

Šta je preflight zahtjev?

Za zahtjeve koji nisu jednostavni, poput JSON POST zahtjeva ili zahtjeva sa zaglavljem Authorization, pregledač prvo šalje OPTIONS zahtjev i pita server koje metode i zaglavlja su dozvoljena. Ako taj OPTIONS zahtjev padne ili nema ispravna zaglavlja, pravi zahtjev se nikada ne šalje.

Mythex · Pricing · Izradite bilo šta uz AI · Šabloni za web stranice i aplikacije · Mythex u poređenju · Rječnik izrade aplikacija uz AI · Besplatni alati za izradu aplikacija uz AI · English

English አማርኛ العربية Български বাংলা Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)