Rokasgrāmatas

Kā novērst CORS kļūdas (un kāpēc tās rodas)

CORS kļūda nozīmē, ka tava tīmekļa lapa mēģināja nolasīt atbildi no citas izcelsmes (cita domēna, porta vai protokola), un šis serveris nenosūtīja galvenes, kas to atļauj. Pārlūki bloķē atbildi, lai aizsargātu lietotājus. Labojums ir serverī: atgriez galveni Access-Control-Allow-Origin savas vietnes izcelsmei un apstrādā OPTIONS preflight pieprasījumus. Alternatīvi to var izvairīties, sūtot pieprasījumu caur savu backend tajā pašā izcelsmē.

Tā ir viena no mulsinošākajām kļūdām tīmekļa izstrādē, jo pieprasījums bieži sasniedz serveri normāli. Šis ceļvedis izskaidro, kas notiek, un kā novērst katru variantu.

Ko nozīmē „izcelsme”

Izcelsme ir protokola, domēna un porta kombinācija:

URLIzcelsme
https://myapp.com/dashboardhttps://myapp.com
https://api.myapp.com/usershttps://api.myapp.com (cits apakšdomēns, tātad cita izcelsme)
http://localhost:5173http://localhost:5173
http://localhost:3000http://localhost:3000 (cits ports, tātad cita izcelsme)

Pārlūki ievēro vienas izcelsmes politiku: lapas JavaScript var brīvi lasīt atbildes no savas izcelsmes, bet ne no citām. CORS (Cross-Origin Resource Sharing) ir sistēma, ar kuru serveris pats piekrīt: „atbildes no manis var lasīt lapas no šīm izcelsmēm”.

Divas sekas pārsteidz cilvēkus:

  • Pieprasījums bieži sasniedz serveri. CORS parasti bloķē tavam kodam atbildes lasīšanu, nevis serverim pieprasījuma saņemšanu. POST var būt saglabāts, pat ja redzēji kļūdu.
  • To izpilda tikai pārlūki. curl, Postman un servera puses kods CORS ignorē pilnībā. Tāpēc „darbojas Postman” neko nepasaka par CORS.

1. solis: izlasi precīzo kļūdu

Atver izstrādātāju rīkus (ar peles labo pogu → Inspect), dodies uz Console un izlasi pilno ziņojumu. Chrome formulējums norāda, kāda problēma tev ir:

Ziņojums saturKas nav kārtībā
No 'Access-Control-Allow-Origin' header is presentServeris nenosūtīja galveni vispār, vai pieprasījums neizdevās pirms nonākšanas līdz tavam CORS kodam (piemēram, 404 vai 500)
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied originServeris atļauj citu izcelsmi nekā tava
Response to preflight request doesn't pass access control checkOPTIONS preflight neizdevās
...must not be the wildcard '*' when the request's credentials mode is 'include'Tu sūti sīkdatnes, un serveris atbildēja ar *
Request header field authorization is not allowedServeris nav uzskaitījis šo galveni Access-Control-Allow-Headers

Tad atver cilni Network, atrodi neizdevušos pieprasījumu (un jebkuru OPTIONS pieprasījumu pirms tā) un apskati tā statusa kodu un atbildes galvenes.

Vispirms pārbaudi statusa kodu. Daudzas „CORS kļūdas” patiesībā ir servera kļūda maskā. Ja serveris avarē vai atgriež 404, tā kļūdas atbilde bieži nesatur CORS galvenes, tāpēc pārlūks ziņo par CORS, nevis par īsto problēmu. Labo 500 vai 404, un CORS kļūda var pazust.

2. solis: izlem, vai no pārlūka vispār jāsauc šis API

Pirms pievienot galvenes, pajautā: vai pārlūkam vajadzētu sūtīt pieprasījumus tieši uz šo API?

  • Trešās puses API, kam vajadzīga slepenā atslēga (OpenAI, Stripe slepenā atslēga, lielākā daļa e-pasta pakalpojumu) nekad nedrīkst izsaukt no pārlūka. Atslēga būtu redzama katram apmeklētājam. Izsauc to no sava backend, un CORS problēma pazūd, jo servera-uz-servera pieprasījumi uz CORS neattiecas. Skaties kā glabāt API atslēgas drošībā.
  • Trešās puses API, ko tu nekontrolē un kas nesūta CORS galvenes, no tavas puses nevar salabot. Izsauc to no sava backend.
  • Tavs pats API var tikt salabots, to pareizi konfigurējot. Turpini tālāk.

3. solis: labo serverī

Serverim jāpievieno pareizās galvenes visām atbildēm, arī kļūdu atbildēm.

Faktiskam pieprasījumam nosūti:

  • Access-Control-Allow-Origin: https://myapp.com (tava frontend precīzā izcelsme, bez slīpsvītras beigās)
  • Vary: Origin, ja vērtība ir atkarīga no tā, kura izcelsme pieprasīja

Preflight OPTIONS pieprasījumam atbildi ar veiksmes statusu (200 vai 204) un:

  • Access-Control-Allow-Origin: https://myapp.com
  • Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
  • Access-Control-Allow-Headers: Content-Type, Authorization (katra pielāgotā galvene, ko sūti)
  • Pēc izvēles Access-Control-Max-Age: 600, lai pārlūks kādu laiku kešotu preflight

Lielākajā daļā ietvaru ir pakotne vai iestatījums, kas to dara. Express — pakotne cors; FastAPI — CORSMiddleware; ASP.NET Core — AddCors; Spring — @CrossOrigin vai CORS konfigurācija. Tipisks Express iestatījums:

import cors from "cors";

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

Ieliec CORS apstrādi pirms savu maršrutu un autentifikācijas, lai preflight pieprasījumi (kuros nav pieteikšanās) netiktu noraidīti ar 401.

Ar AI veidotāju apraksti iestatījumu precīzi:

Frontend https://myapp.com izsauc API https://api.myapp.com un saņem „Response to preflight request doesn't pass access control check”. Konfigurē CORS API, lai atļautu tieši https://myapp.com un priekšskatījuma izcelsmi, atļauj GET, POST, PATCH, DELETE ar galvenēm Content-Type un Authorization, apstrādā OPTIONS pirms autentifikācijas un iekļauj CORS galvenes arī kļūdu atbildēs.

4. solis: apstrādā sīkdatnes un akreditācijas datus

Ja tavs frontend sūta sīkdatnes (piemēram, pieteikšanās sesiju) uz citu izcelsmi, abām pusēm jāsaskaņojas:

  • Frontend fetch iestata credentials: "include", vai axios withCredentials: true.
  • Serveris nosūta Access-Control-Allow-Credentials: true.
  • Servera Access-Control-Allow-Origin jābūt precīzai izcelsmei, nevis *.

Starpvietņu sīkdatnēm arī vajag SameSite=None; Secure, un daži pārlūki ierobežo trešo pušu sīkdatnes vēl vairāk. Tas ir vēl viens iemesls dot priekšroku 5. solī aprakstītajai pieejai.

5. solis: izvairies no CORS ar vienas izcelsmes iestatījumu

Bieži tīrākais labojums ir nesūtīt starpizcelsmju pieprasījumus vispār. Pasniedz API no tās pašas izcelsmes, kur lapa, piemēram, https://myapp.com/api/...:

  • Izstrādes vidē lielākā daļa izstrādes serveru var starpniekot. Vite opcija server.proxy var pārsūtīt /api uz tavu backend citā portā, tāpēc pārlūks vienmēr runā tikai ar vienu izcelsmi.
  • Ražošanā maršrutē /api uz backend ar sava hostinga pārrakstīšanas vai starpnieka iestatījumiem, vai pasniedz frontend un API no viena servera.

Tad frontend sauc relatīvu ceļu, piemēram, fetch("/api/orders"). Nav starpizcelsmju pieprasījuma, nav starpizcelsmju preflight un nav sīkdatņu problēmu. Tas arī nozīmē, ka tu nekodē API domēnu, kas atšķiras starp priekšskatījumu un ražošanu.

Maini frontend, lai tas sauktu backend ar relatīviem /api ceļiem, nevis pilnu URL, un iestati izstrādes starpnieku, lai /api pārsūtītu uz API serveri. Pēc tam noņem CORS iestatījumus, kas vairs nav vajadzīgi.

Ko nedarīt

  • mode: "no-cors" fetch. Tas neko neapiet; tas dod tavam kodam tukšu, nelasāmu atbildi.
  • Pārlūka paplašinājumi, kas atslēdz CORS. Tie maina tikai tavu pārlūku. Katrs apmeklētājs joprojām redz kļūdu.
  • Publiski „CORS starpnieka” pakalpojumi reāliem lietotnēm. Tie var lasīt un mainīt visu, kas tiem iet cauri, un tie reizēm nedarbojas.
  • Access-Control-Allow-Origin: * API, kas izmanto pieteikšanos. Tas tāpat nedarbojas ar akreditācijas datiem, un tas ir nepareizs noklusējums privātiem datiem.
  • Atgriezt jebkuru Origin galveni atpakaļ, ļaujot akreditācijas datus. Tas ļauj jebkurai tīmekļa vietnei veikt pieprasījumus ar pieteikšanos tavu lietotāju vārdā. Izmanto atļauto sarakstu.

Biežākie cēloņi AI veidotās lietotnēs

SituācijaLabojums
Frontend sauc trešās puses API ar slepenu atslēguPārvieto izsaukumu uz backend
Darbojas priekšskatījumā, neizdodas publicētajā domēnāPievieno publicētās un pielāgotā domēna izcelsmes atļauto sarakstā vai izmanto relatīvus /api ceļus
Kļūda tikai uz POST, PUT vai DELETEPreflight nav apstrādāts; pievieno OPTIONS apstrādi un atļautās galvenes
Kļūda parādījās pēc pieteikšanās pievienošanasAkreditācijas datiem vajadzīga precīza izcelsme un Allow-Credentials
„CORS kļūda”, bet tīkla cilnē redzams 500Vispirms labo servera kļūdu
API URL cieti ierakstīts uz localhostLieto relatīvus ceļus vai iestatījumu katrai videi

CORS Mythex

Kad Mythex projektam ir gan vietne, gan API serveris, abi darbojas kā pakalpojumi vienā projektā, un starp tiem var pārslēgties priekšskatījumā. Ja aģentam lūdz, lai frontend sauc backend caur relatīvu /api ceļu, izstrādē starpniekotu, vairums CORS problēmu pazūd. Ja tomēr vajag starpizcelsmju izsaukumus, dod aģentam precīzo kļūdu no konsoles un iesaistītās izcelsmes. Pārbaudi rezultātu arī publicētajā lietotnē, jo tās adrese atšķiras no priekšskatījuma. Skaties Vairāku pakalpojumu lietotnes un API backend dokumentācijā, kā arī mūsu ceļvežus kā atkļūdot ar AI veidotu lietotni un frontend pret backend.

CORS kontrolsaraksts

  • Izlasīta pilna konsoles kļūda un neizdevušos pieprasījuma statusa kods
  • Izslēgta paslēpta 404 vai 500 kļūda
  • API ar slepenām atslēgām tiek izsaukti no backend, nevis pārlūka
  • Serveris nosūta Access-Control-Allow-Origin ar precīzi atļautajām izcelsmēm
  • OPTIONS preflight atbildēts ar atļautajām metodēm un galvenēm, pirms autentifikācijas
  • CORS galvenes ir arī kļūdu atbildēs
  • Akreditācijas dati: precīza izcelsme, Allow-Credentials: true un pareizi sīkdatņu iestatījumi
  • Priekšskatījuma, publicētā un pielāgotā domēna izcelsmes aptvertas, vai izmantoti relatīvi /api ceļi
  • Nav no-cors, publisku starpnieku vai atgriešanas jebkuras izcelsmes saīsinājumu

Jautājumi

Ko nozīmē CORS kļūda?

Tava lapa, ielādēta no vienas izcelsmes, mēģināja nolasīt atbildi no citas izcelsmes, un tā servera atbildē nebija galveņu, kas to atļauj. Pārlūks bloķē tavam kodam atbildes nolasīšanu. Labojums ir serverī vai tajā, kā pieprasījums tiek maršrutēts, nevis frontend kodā.

Vai CORS kļūdu var novērst no frontend?

Ne pienācīgi. Iestatījumi, piemēram, mode: 'no-cors', tikai paslēpj atbildi no tava koda. To labo, liekot serverim nosūtīt pareizo galveni Access-Control-Allow-Origin, vai izsaucot API no sava backend vai vienas izcelsmes starpnieka.

Vai Access-Control-Allow-Origin: * ir drošs?

Tas ir labi publiskiem datiem, ko var lasīt ikviens, piemēram, publiskam API bez pieteikšanās. To nevar lietot ar sīkdatnēm vai citiem akreditācijas datiem, un privātiem API tev jāuzskaita precīzas atļautās izcelsmes.

Kāpēc pieprasījums darbojas Postman vai curl, bet ne pārlūkā?

CORS izpilda tikai pārlūki. Tādi rīki kā Postman un curl to nepiemēro, tāpēc pieprasījums tur var izdoties un tomēr tikt bloķēts, kad to veic lapas JavaScript.

Kas ir preflight pieprasījums?

Pieprasījumiem, kas nav vienkārši, piemēram, JSON POST vai pieprasījumam ar galveni Authorization, pārlūks vispirms nosūta OPTIONS pieprasījumu, jautājot serverim, kādas metodes un galvenes ir atļautas. Ja šis OPTIONS pieprasījums neizdodas vai nesatur pareizās galvenes, īstais pieprasījums nekad netiek nosūtīts.

Mythex · Pricing · Veidojiet jebko ar AI · Tīmekļa vietņu un lietotņu veidnes · Mythex salīdzinājumā · AI lietotņu veidošanas glosārijs · Bezmaksas rīki lietotņu veidošanai ar AI · English

English አማርኛ العربية Български বাংলা Bosanski 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ų Македонски മലയാളം Монгол मराठी 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 简体中文 繁體中文(香港) 繁體中文(台灣)