CORS қателерін түзету және олар неге пайда болады
CORS қатесі веб-бетіңіздің басқа шығу-тегінен (басқа домен, порт немесе протокол) жауапты оқуға тырысқанын, ал сол сервер рұқсат берілгенін білдіретін тақырыптар жібермегенін білдіреді. Браузерлер пайдаланушыны қорғау үшін жауапты блоктайды. Оны серверде түзетесіз: сайтыңыздың шығу-тегі үшін Access-Control-Allow-Origin тақырыбын қайтарып, OPTIONS preflight сұрауларын өңдейсіз, немесе өз бэкендіңіз арқылы бірдей шығу-тегінде сұрау жіберіп, оны мүлде болдырмайсыз.
Бұл веб әзірлеудегі ең түсініксіз қателердің бірі, себебі сұраным көбіне серверге дұрыс жетеді. Бұл нұсқаулық не болып жатқанын және әр нұсқаны қалай түзетуді түсіндіреді.
«Шығу-тегі» дегеніміз не
Шығу-тегі — протокол, домен және порттың тіркесімі:
| 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 (басқа порт, демек басқа шығу-тегі) |
Браузерлер бірдей шығу-тегі саясатын ұстанады: беттегі JavaScript өз шығу-тегінің жауаптарын еркін оқи алады, бірақ басқаларынан оқи алмайды. CORS (Cross-Origin Resource Sharing) — серверге өз еркімен рұқсат беру жүйесі: «менің жауаптарымды мына шығу-тегінен келетін беттер оқи алады».
Көп адамды таң қалдыратын екі нәрсе бар:
- Сұраным көбіне серверге жетеді. CORS әдетте сіздің кодыңыздың жауапты оқуын блоктайды, серверге сұранымды қабылдауға кедергі келтірмейді. POST сақталуы мүмкін, сол кезде сіз қате көрдіңіз.
- Тек браузерлер мұны орындайды. curl, Postman және серверлік код CORS-ты мүлде елемейді. Сондықтан «Postman-де жұмыс істейді» дегеннің CORS туралы ешқандай мәні жоқ.
1-қадам: Нақты қатені оқыңыз
Development құралдарын ашыңыз (тінтуірдің оң жағы → 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 құпия кілті, көпшілік электрондық пошта қызметтері) браузерден ешқашан шақырылмауы керек. Кілт әр келушіге көрінеді. Оны бэкендтен шақырыңыз, сонда CORS мәселесі жоғалады, себебі сервер-сервер сұраулары CORS-қа бағынбайды. API кілттерін қалай қауіпсіз сақтау керек қараңыз.
- Сіз басқармайтын, CORS тақырыптарын жібермейтін үшінші тарап API-і сіздің тарапыңыздан түзетілмейді. Оны бэкендтен шақырыңыз.
- Өз 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-дағы фронтендhttps://api.myapp.comAPI-ін шақырады және «Response to preflight request doesn't pass access control check» қатесін алады. API-де CORS-ты дәлhttps://myapp.comжәне превью шығу-тегіне рұқсат ететіндей баптаңыз, Content-Type және Authorization тақырыптарымен GET, POST, PATCH, DELETE әдістеріне рұқсат беріңіз, OPTIONS-ті аутентификацияға дейін өңдеңіз және CORS тақырыптары қате жауаптарға да кірсін.
4-қадам: Cookie және credentials-ті өңдеңіз
Фронтенд басқа шығу-тегіне cookie (мысалы, кіру сессиясы) жіберсе, екі жақ та келісуі керек:
- Фронтенд
fetch-теcredentials: "include", немесе axios-таwithCredentials: trueорнатады. - Сервер
Access-Control-Allow-Credentials: trueжібереді. - Сервердің
Access-Control-Allow-Originмәні дәл шығу-тегі болуы керек,*емес.
Шығу-тегі басқа сайттағы cookie-ге SameSite=None; Secure керек, ал кейбір браузерлер үшінші тарап cookie-лерін қатаңырақ шектейді. Бұл сізге 5-қадамдағы тәсілді таңдауға тағы бір себеп.
5-қадам: Бірдей шығу-тегі баптауымен CORS-тан аулақ болыңыз
Көбіне ең таза түзету — мүлде шығу-тегіне сұраныс жібермеу. API-ді бет сияқты бірдей шығу-тегінен қызмет етіңіз, мысалы https://myapp.com/api/...:
- Дамуда көптеген dev серверлері проксилей алады. Vite-тің
server.proxyбаптауы/api-ді басқа портта тұрған бэкендке жібере алады, сонда браузер тек бір шығу-тегімен сөйлеседі. - Өндірісте
/api-ді бэкендке хостыңыздың rewrite немесе прокси баптауы арқылы бағыттаңыз, немесе фронтенд пен API-ді бір серверден қызмет етіңіз.
Содан кейін фронтенд салыстырмалы жолды шақырады, мысалы fetch("/api/orders"). Шығу-тегі аралық сұраныс, шығу-тегі аралық preflight және cookie қиындықтары болмайды. Сондай-ақ превью мен өндіріс арасында айырмашылық болатын API доменін қатты жазудың қажеті жоқ.
Фронтендті API-ге толық URL орнына салыстырмалы /api жолдары арқылы шақыртыңыз, және /api-ді API серверіне жіберетін dev проксиін орнатыңыз. Содан кейін енді қажет емес CORS баптауларын алып тастаңыз.
Не істемеу керек
fetch-теmode: "no-cors". Ол ештеңені айналып өтпейді; кодыңызға бос, оқылмайтын жауап береді.- CORS-ты өшіретін браузер кеңейтулері. Олар тек сіздің браузеріңізді өзгертеді. Әр келуші қатені көреді.
- Жалпыға ортақ «CORS прокси» қызметтері нақты қолданбалар үшін. Олар арқылы өтетін барлығын оқи және өзгерте алады, және олар құлап қалуы мүмкін.
- Кіру пайдаланатын API-де
Access-Control-Allow-Origin: *. Ол credentials-пен жұмыс істемейді, және жеке деректер үшін дұрыс әдепкі емес. - Кез келген
Originтақырыбын кері қайтару credentials рұқсатымен. Бұл кез келген веб-сайтқа пайдаланушыларыңыздың атынан кіруі бар сұраныс жіберуге мүмкіндік береді. Рұқсат тізімін қолданыңыз.
AI көмегімен жасалған қолданбалардағы жиі кездесетін себептер
| Жағдай | Түзету |
|---|---|
| Фронтенд құпия кілті бар үшінші тарап API-ін шақырады | Шақыруды бэкендке көшіріңіз |
| Превьюде жұмыс істейді, жарияланған доменде істемейді | Жарияланған және теңшелген домен шығу-тегтерін рұқсат тізіміне қосыңыз, немесе салыстырмалы /api жолдарын қолданыңыз |
| Қате тек POST, PUT немесе DELETE-де | Preflight өңделмеген; OPTIONS өңдеуін және рұқсат етілген тақырыптарды қосыңыз |
| Кіру қосқаннан кейін қате пайда болды | Credentials дәл шығу-тегін және Allow-Credentials-ті талап етеді |
| «CORS қатесі», бірақ Network 500 көрсетеді | Алдымен сервердегі қатені түзетіңіз |
API URL localhost-қа қатты жазылған | Салыстырмалы жолдарды немесе әр ортаға арналған баптауды қолданыңыз |
Mythex-тегі CORS
Mythex жобасында веб-сайт пен API сервері болғанда, екеуі де бір жобадағы қызмет ретінде іске қосылады, және превьюде екеуінің арасында ауыса аласыз. Агентке фронтендтің бэкендті салыстырмалы /api жолы арқылы шақыруын сұрау, дамуда проксиленген, CORS мәселелерінің көбін болдырмайды. Шығу-тегі аралық шақырулар қажет болса, агентке консольдегі дәл қатені және қатысты шығу-тектерді беріңіз. Нәтижені жарияланған қолданбада да тексеріңіз, өйткені оның мекенжайы превьюден өзгеше. Құжаттарда Көп қызметті қолданбалар және API бэкендтері бар, ал біздің нұсқаулықтардан AI құрастырған қолданбаны түзету және фронтенд пен бэкенд қараңыз.
CORS тексеру тізімі
- Толық консоль қатесі және сәтсіз сұраным статус коды оқылды
- Жасырын 404 немесе 500 жоққа шығарылды
- Құпия кілтті API-лер браузерден емес, бэкендтен шақырылады
- Сервер нақты рұқсат етілген шығу-тегтермен
Access-Control-Allow-Originжібереді -
OPTIONSpreflight рұқсат етілген әдістермен және тақырыптармен аутентификацияға дейін жауап береді - CORS тақырыптары қате жауаптарда да бар
- Credentials: дәл шығу-тегі,
Allow-Credentials: true, дұрыс cookie баптаулары - Превью, жарияланған және теңшелген домен шығу-тегтері қамтылған, немесе салыстырмалы
/apiжолдары қолданылған -
no-cors, жалпыға ортақ проксилер және кез келген origin-ді кері қайтару жолдары жоқ
Сұрақтар
CORS қатесі нені білдіреді?
Бір шығу-тегінен жүктелген бетіңіз басқа шығу-тегінен жауапты оқуға тырысты, ал сол сервердің жауабында рұқсат беретін тақырыптар болмады. Браузер кодыңыздың жауапты оқуын блоктайды. Түзету серверде немесе сұраныстың бағытталуында, фронтенд кодында емес.
CORS қатесін фронтенд жағынан түзетуге бола ма?
Дұрыс емес. mode: 'no-cors' сияқты баптаулар жауапты тек кодыңыздан жасырады. Оны серверге дұрыс Access-Control-Allow-Origin тақырыбын жібертіп, немесе API-ді өз бэкендіңізден немесе бірдей шығу-тегі проксиінен шақыртып түзетесіз.
Access-Control-Allow-Origin: * қауіпсіз бе?
Кез келген адам оқи алатын ашық деректер үшін жарайды, мысалы кіруді талап етпейтін ашық API. Оны cookie немесе басқа credentials-пен қолдануға болмайды, ал жеке API-лер үшін рұқсат етілген нақты origin-дерді тізімдеу керек.
Сұраным Postman немесе curl-да жұмыс істейді, бірақ браузерде неге жұмыс істемейді?
CORS тек браузерлерде орындалады. Postman және curl сияқты құралдар оны қолданбайды, сондықтан сұраным сонда сәтті болуы мүмкін, ал беттің JavaScript-і жасағанда блокталады.
Preflight сұрауы дегеніміз не?
Қарапайым емес сұраулар үшін, мысалы JSON POST немесе Authorization тақырыбы бар сұрау үшін, браузер алдымен OPTIONS сұрауын жібереді де, серверден қандай әдістер мен тақырыптарға рұқсат екенін сұрайды. Егер бұл OPTIONS сұрауы сәтсіз болса немесе дұрыс тақырыптары болмаса, нақты сұраным ешқашан жіберілмейді.