Ինչպես շտկել CORS սխալները (և ինչու են դրանք առաջանում)
CORS սխալը նշանակում է, որ ձեր վեբ էջը փորձել է կարդալ պատասխան մեկ այլ ծագումից (այլ դոմեն, պորտ կամ արձանագրություն), և այդ սերվերը չի ուղարկել վերնագրեր, որոնք ասում են, որ դա թույլատրված է։ Բրաուզերները արգելափակում են պատասխանը՝ օգտատերերին պաշտպանելու համար։ Շտկում եք սերվերի վրա՝ վերադարձնելով Access-Control-Allow-Origin վերնագիր ձեր կայքի ծագման համար և մշակելով OPTIONS preflight հարցումները, կամ խուսափում եք դրանից՝ հարցումն ուղարկելով ձեր սեփական backend-ի միջոցով, նույն ծագման վրա։
Սա ամենաշփոթեցնող սխալներից մեկն է վեբ մշակման մեջ, քանի որ հարցումը հաճախ սերվերին հասնում է լավ։ Այս ուղեցույցը բացատրում է, թե ինչ է կատարվում և ինչպես շտկել յուրաքանչյուր տարբերակ։
Ինչ է նշանակում «ծագում»
Ծագումը արձանագրության, դոմենի և պորտի համադրությունն է․
| URL | Ծագում |
|---|---|
https://myapp.com/dashboard | https://myapp.com |
https://api.myapp.com/users | https://api.myapp.com (այլ ենթադոմեն, հետևաբար այլ ծագում) |
http://localhost:5173 | http://localhost:5173 |
http://localhost:3000 | http://localhost:3000 (այլ պորտ, հետևաբար այլ ծագում) |
Բրաուզերները հետևում են նույն ծագման քաղաքականությանը (same-origin policy)․ էջի JavaScript-ը ազատորեն կարող է կարդալ սեփական ծագումից պատասխանները, բայց ոչ այլ ծագումներից։ CORS-ը (Cross-Origin Resource Sharing) համակարգն է, որով սերվերը միանում է․ «իմ պատասխանները կարող են կարդալ այս ծագումներից եկող էջերը»։
Երկու հետևանք զարմացնում է մարդկանց․
- Հարցումը հաճախ հասնում է սերվերին։ CORS-ը սովորաբար արգելափակում է ձեր կոդի կողմից պատասխանի կարդալը, ոչ թե սերվերի կողմից հարցումը ստանալը։ POST-ը կարող է պահպանվել, նույնիսկ եթե սխալ եք տեսել։
- Միայն բրաուզերներն են կիրառում այն։ curl-ը, Postman-ը և սերվերային կոդը CORS-ը ամբողջությամբ անտեսում են։ Դրա համար «աշխատում է Postman-ում» ոչինչ չի ասում CORS-ի մասին։
Քայլ 1. Կարդացեք ճշգրիտ սխալը
Բացեք մշակողի գործիքները (աջ կտտոց → Inspect), գնացեք Console և կարդացեք ամբողջական հաղորդագրությունը։ Chrome-ի ձևակերպումը ասում է, թե ինչ խնդիր ունեք․
| Հաղորդագրությունը պարունակում է | Ինչն է սխալ |
|---|---|
No 'Access-Control-Allow-Origin' header is present | Սերվերը ընդհանրապես չի ուղարկել վերնագիրը, կամ հարցումը ձախողվել է մինչև ձեր CORS կոդին հասնելը (օրինակ՝ 404 կամ 500) |
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied origin | Սերվերը թույլ է տալիս այլ ծագում, քան ձերը |
Response to preflight request doesn't pass access control check | OPTIONS preflight-ը ձախողվել է |
...must not be the wildcard '*' when the request's credentials mode is 'include' | Դուք ուղարկում եք cookie-ներ, իսկ սերվերը պատասխանել է *-ով |
Request header field authorization is not allowed | Սերվերը չի թվարկել այդ վերնագիրը Access-Control-Allow-Headers-ում |
Հետո բացեք Network ներդիրը, գտեք ձախողված հարցումը (և դրանից առաջ եկած ցանկացած OPTIONS հարցում) և նայեք դրա կարգավիճակի կոդին և պատասխանի վերնագրերին։
Նախ ստուգեք կարգավիճակի կոդը։ Շատ «CORS սխալներ» իրականում սերվերի սխալ են քողարկված։ Եթե սերվերը կոտրվում է կամ վերադարձնում է 404, նրա սխալի պատասխանին հաճախ բացակայում են CORS վերնագրերը, ուստի բրաուզերը հայտնում է CORS՝ իրական խնդրի փոխարեն։ Շտկեք 500-ը կամ 404-ը, և CORS սխալը կարող է անհետանալ։
Քայլ 2. Որոշեք, արդյոք այդ API-ին ընդհանրապես պետք է կանչել բրաուզերից
Վերնագրեր ավելացնելուց առաջ հարցրեք․ պե՞տք է արդյոք բրաուզերը ուղղակիորեն կանչի այս API-ին։
- Երրորդ կողմի API, որը պահանջում է գաղտնի բանալի (OpenAI, Stripe-ի գաղտնի բանալի, շատ էլ․ փոստի ծառայություններ) երբեք չպետք է կանչվի բրաուզերից։ Բանալին տեսանելի կլինի յուրաքանչյուր այցելուի համար։ Կանչեք այն ձեր backend-ից, և CORS խնդիրը վերանում է, քանի որ սերվեր-սերվեր հարցումները CORS-ի ենթակա չեն։ Տես ինչպես պահել API բանալիները անվտանգ։
- Երրորդ կողմի API, որը չեք վերահսկում, և որը CORS վերնագրեր չի ուղարկում, ձեր կողմից չի կարող շտկվել։ Կանչեք այն ձեր backend-ից։
- Ձեր սեփական API-ը կարելի է շտկել ճիշտ կարգավորելով։ Շարունակեք ստորև։
Քայլ 3. Շտկեք սերվերի վրա
Սերվերը պետք է ճիշտ վերնագրեր ավելացնի իր պատասխաններին, ներառյալ սխալի պատասխանները։
Իրական հարցման համար ուղարկեք․
Access-Control-Allow-Origin: https://myapp.com(ձեր ճակատի ճշգրիտ ծագումը, առանց վերջին սլաշի)Vary: Origin, եթե արժեքը կախված է նրանից, թե որ ծագումն է հարցրել
Preflight OPTIONS հարցման համար պատասխանեք հաջողության կարգավիճակով (200 կամ 204) և՝
Access-Control-Allow-Origin: https://myapp.comAccess-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETEAccess-Control-Allow-Headers: Content-Type, Authorization(յուրաքանչյուր սովորական վերնագիր, որ ուղարկում եք)- Ըստ ցանկության՝
Access-Control-Max-Age: 600, որպեսզի բրաուզերը preflight-ը որոշ ժամանակ քեշավորի
Ամենաշատ ֆրեյմվորքները ունեն փաթեթ կամ կարգավորում, որը սա անում է։ Express-ում՝ cors փաթեթը, FastAPI-ում՝ CORSMiddleware, ASP.NET Core-ում՝ AddCors, Spring-ում՝ @CrossOrigin կամ CORS կոնֆիգուրացիա։ Տիպային Express կարգավորում․
import cors from "cors";
app.use(cors({
origin: ["https://myapp.com", "http://localhost:5173"],
credentials: true,
}));
Դրեք CORS մշակումը նախքան ձեր երթուղիները և նույնականացումը, որպեսզի preflight հարցումները (որոնք մուտք չեն պարունակում) չմերժվեն 401-ով։
AI կառուցողով նկարագրեք կարգավորումը ճշգրիտ․
Ճակատը
https://myapp.com-ում կանչում է API-նhttps://api.myapp.com-ում և ստանում է «Response to preflight request doesn't pass access control check»։ Կարգավորիր CORS API-ում, որ թույլ տա ճիշտhttps://myapp.com-ը և նախադիտման ծագումը, թույլ տա GET, POST, PATCH, DELETE՝ Content-Type և Authorization վերնագրերով, մշակիր OPTIONS նույնականացումից առաջ և ներառիր CORS վերնագրերը սխալի պատասխաններում նույնպես։
Քայլ 4. Կարգավորեք cookie-ները և credentials-ը
Եթե ձեր ճակատը cookie-ներ է ուղարկում (օրինակ՝ մուտքի սեսիա) մեկ այլ ծագման, երկու կողմերը պետք է համաձայնվեն․
- Ճակատը դնում է
credentials: "include"fetch-ում, կամwithCredentials: trueaxios-ում։ - Սերվերը ուղարկում է
Access-Control-Allow-Credentials: true։ - Սերվերի
Access-Control-Allow-Origin-ը պետք է լինի ճշգրիտ ծագում, ոչ թե*։
Խաչ-կայքային cookie-ներին նույնպես պետք է SameSite=None; Secure, և որոշ բրաուզերներ լրացուցիչ սահմանափակում են երրորդ կողմի cookie-ները։ Դա ևս մեկ պատճառ է նախընտրել 5-րդ քայլում նկարագրված մոտեցումը։
Քայլ 5. Խուսափեք CORS-ից նույն ծագման կարգավորմամբ
Հաճախ ամենամաքուր շտկումը այն է, որ խաչ-ծագումային հարցումներ ընդհանրապես չանեք։ Սպասարկեք API-ն նույն ծագումից, ինչ էջը, օրինակ՝ https://myapp.com/api/...-ում։
- Մշակման ժամանակ շատ զարգացման սերվերներ կարող են պրոքսիավորել։ Vite-ի
server.proxyկարգավորումը կարող է/api-ն փոխանցել ձեր backend-ին այլ պորտում, այնպես որ բրաուզերը երբեք չի խոսում ավելի քան մեկ ծագման հետ։ - Արտադրության մեջ երթուղավորեք
/api-ը backend-ին հոսթի rewrite կամ պրոքսի կարգավորումների միջոցով, կամ սպասարկեք ճակատը և API-ն մեկ սերվերից։
Որից հետո ճակատը կանչում է հարաբերական ուղի, օրինակ՝ fetch("/api/orders")։ Չկա խաչ-ծագումային հարցում, չկան խաչ-ծագումային preflight-ներ և cookie-ների խնդիրներ։ Սա նաև նշանակում է, որ չեք կոշտ կոդավորում API դոմեն, որը տարբերվում է նախադիտման և արտադրության միջև։
Փոխիր ճակատը, որ կանչի backend-ը հարաբերական /api ուղիներով՝ լրիվ URL-ի փոխարեն, և կարգավորիր մշակման պրոքսի, որ /api-ն ուղարկվի API սերվերին։ Ապա հեռացրու այն CORS կարգավորումները, որոնք այլևս պետք չեն։
Ինչ չանել
mode: "no-cors"fetch-ում։ Ոչինչ չի շրջանցում․ այն ձեր կոդին տալիս է դատարկ, չկարդացվող պատասխան։- Բրաուզերի ընդլայնումներ, որոնք անջատում են CORS-ը։ Դրանք փոխում են միայն ձեր բրաուզերը։ Յուրաքանչյուր այցելու դեռ տեսնում է սխալը։
- Հանրային «CORS պրոքսի» ծառայություններ իրական հավելվածների համար։ Դրանք կարող են կարդալ և փոխել ամեն ինչ, որ անցնում է դրանց միջով, և երբեմն անջատվում են։
Access-Control-Allow-Origin: *API-ի վրա, որը օգտագործում է մուտք։ Այն նույնպես չի աշխատում credentials-ի հետ, և մասնավոր տվյալների համար սխալ լռելյայն է։- Ցանկացած
Originվերնագիր արտացոլել հետ, թույլատրված credentials-ով։ Դա թույլ է տալիս ցանկացած կայքի կատարել մուտքագրված հարցումներ ձեր օգտատերերի անունից։ Օգտագործեք թույլատրված ցուցակ։
Սովորական պատճառները AI-ով կառուցված հավելվածներում
| Իրավիճակ | Շտկում |
|---|---|
| Ճակատը կանչում է երրորդ կողմի API գաղտնի բանալիով | Տեղափոխեք կանչը backend-ին |
| Աշխատում է նախադիտման մեջ, ձախողվում է հրապարակված դոմենում | Ավելացրեք հրապարակված և սեփական դոմենի ծագումները թույլատրված ցուցակում, կամ օգտագործեք հարաբերական /api ուղիներ |
| Սխալ է միայն POST, PUT կամ DELETE-ի վրա | Preflight-ը չի մշակվում․ ավելացրեք OPTIONS մշակում և թույլատրված վերնագրեր |
| Սխալը հայտնվել է մուտքը ավելացնելուց հետո | Credentials-ին պետք է ճշգրիտ ծագում և Allow-Credentials |
| «CORS սխալ», բայց Network ներդիրը ցույց է տալիս 500 | Նախ շտկեք սերվերի սխալը |
API URL-ը կոշտ կոդավորված է localhost-ի վրա | Օգտագործեք հարաբերական ուղիներ կամ միջավայրի առանձին կարգավորում |
CORS Mythex-ում
Երբ Mythex նախագիծը ունի կայք և API սերվեր, երկուսն էլ աշխատում են որպես ծառայություններ նույն նախագծում, և դուք կարող եք անցնել դրանց միջև նախադիտման մեջ։ Եթե գործակալից խնդրեք, որ ճակատը կանչի backend-ը հարաբերական /api ուղիով, որը մշակման ժամանակ պրոքսիավորվում է, CORS խնդիրների մեծ մասից խուսափում եք։ Եթե իրոք պետք են խաչ-ծագումային կանչեր, տվեք գործակալին կոնսոլի ճշգրիտ սխալը և ներգրավված ծագումները։ Ստուգեք արդյունքը նաև հրապարակված հավելվածի վրա, քանի որ նրա հասցեն տարբերվում է նախադիտումից։ Փաստաթղթերում տես Multi-service apps և API backends, իսկ մեր ուղեցույցներում՝ ինչպես վրիպազերծել AI-ով կառուցված հավելվածը և frontend ընդդեմ backend։
CORS ստուգաթերթ
- Կարդացել եք կոնսոլի ամբողջական սխալը և ձախողված հարցման կարգավիճակի կոդը
- Բացառել եք թաքնված 404-ը կամ 500-ը
- Գաղտնի բանալիներով API-ները կանչվում են backend-ից, ոչ թե բրաուզերից
- Սերվերը ուղարկում է
Access-Control-Allow-Originճշգրիտ թույլատրված ծագումներով -
OPTIONSpreflight-ին պատասխանված է թույլատրված մեթոդներով և վերնագրերով, նույնականացումից առաջ - CORS վերնագրերը առկա են սխալի պատասխաններում նույնպես
- Credentials՝ ճշգրիտ ծագում,
Allow-Credentials: trueև ճիշտ cookie կարգավորումներ - Նախադիտման, հրապարակված և սեփական դոմենի ծագումները բոլորը ծածկված են, կամ օգտագործվում են հարաբերական
/apiուղիներ - Չկան
no-cors, հանրային պրոքսիներ կամ ցանկացած ծագում արտացոլող դյուրանցումներ
Հարցեր
Ի՞նչ է նշանակում CORS սխալը։
Ձեր էջը, բեռնված մի ծագումից, փորձել է կարդալ պատասխան մեկ այլ ծագումից, և այդ սերվերի պատասխանը չի պարունակել թույլտվող վերնագրեր։ Բրաուզերը արգելափակում է ձեր կոդի կողմից պատասխանի կարդալը։ Շտկումը սերվերի վրա է կամ հարցումները երթուղավորելու եղանակում, ոչ թե ճակատի կոդում։
Կարո՞ղ եմ շտկել CORS սխալը ճակատից։
Ոչ իսկապես։ Այնպիսի կարգավորումները, ինչպիսին է mode: 'no-cors'-ը, միայն թաքցնում են պատասխանը ձեր կոդից։ Շտկում եք սերվերը ճիշտ Access-Control-Allow-Origin վերնագիր ուղարկելով, կամ API-ին կանչելով ձեր սեփական backend-ից կամ նույն ծագման պրոքսիից։
Ապահո՞վ է Access-Control-Allow-Origin: * արժեքը։
Լավ է հանրային տվյալների համար, որոնք ցանկացածը կարող է կարդալ, օրինակ՝ մուտքի պահանջ չունեցող հանրային API-ի համար։ Այն չի կարող օգտագործվել cookie-ների կամ այլ credentials-ի հետ, իսկ մասնավոր API-ների համար պետք է թվարկեք թույլատրված ծագումները ճշգրիտ։
Ինչու՞ իմ հարցումը աշխատում է Postman-ում կամ curl-ում, բայց ոչ բրաուզերում։
CORS-ը կիրառվում է միայն բրաուզերների կողմից։ Postman-ի և curl-ի նման գործիքները այն չեն կիրառում, ուստի հարցումը կարող է այնտեղ հաջողվել և դեռ արգելափակվել, երբ էջի JavaScript-ն է այն կատարում։
Ի՞նչ է preflight հարցումը։
Հարցումների համար, որոնք պարզ չեն, օրինակ՝ JSON POST կամ Authorization վերնագրով հարցում, բրաուզերը նախ ուղարկում է OPTIONS հարցում՝ հարցնելով սերվերից, թե որ մեթոդները և վերնագրերն են թույլատրված։ Եթե այդ OPTIONS հարցումը ձախողվում է կամ չունի ճիշտ վերնագրերը, իրական հարցումը երբեք չի ուղարկվում։