CORS-ը React-ում. Ի՞նչ է այն, ինչու է այն կարևոր և ինչպես այն միացնել
Հասկանալով CORS-ը React-ում
CORS-ը (Cross-Origin Resource Sharing) երկար ժամանակ շփոթություն և հիասթափություն է առաջացրել ծրագրավորողների համար, հատկապես նրանց համար, ովքեր նոր են սկսում։ Այս գաղափարը կարող է բարդ թվալ, հատկապես երբ ստեղծում եք single-page հավելվածներ (SPAs) React, Angular կամ Vue ֆրեյմվորքերով և փորձում եք փոխազդել երրորդ կողմի API-ների հետ։
Այս ուղեցույցում կօգնեմ ձեզ հասկանալ CORS-ը հիմնային մակարդակից։ Մենք կկառուցենք պարզ React հավելված՝ Express սերվերի հետ, ցույց տալու համար, թե ինչ է առաջացնում CORS սխալները և ինչու դրանք տեղի են ունենում։ Ավելի կարևորն այն է, որ կանցնենք տարբեր լուծումներ՝ ընդհանուր և կոնկրետ React միջավայրում այս խնդիրները հաղթահարելու համար։
Ի՞նչ է CORS-ը
CORS-ը կամ Cross-Origin Resource Sharing-ը պրոտոկոլ է, որը սահմանում է կանոններ, թե ինչպես կարող են վեբ հավելվածները հարցումներ ուղարկել տարբեր Origin-ներում (տիրույթ, պրոտոկոլ կամ պորտ) տեղակայված սերվերներին։ Ինչպես HTTPS-ը սահմանում է անվտանգ հաղորդակցության կանոններ, այնպես էլ CORS-ը՝ cross-origin հարցումների համար։
Ժամանակակից վեբ հավելվածները սովորաբար բաժանվում են երկու հիմնական մասի՝ հաճախորդ (frontend՝ զննարկչում) և սերվեր (API կամ backend ծառայություն)։ Հաճախորդը հարցում է ուղարկում սերվերին տվյալներ ստանալու համար, և սերվերը վերադարձնում է պատասխան։ Եթե այս երկու մասերը տարբեր տիրույթներում են, CORS-ն է սկսում գործել։
Ինչո՞ւ այս ճարտարապետությունը այսքան տարածված է
Այս «decoupled» (անջատված) ճարտարապետությունը՝ որտեղ frontend-ը և backend-ը առանձին են զարգացվում և տեղադրվում, գնալով ավելի շատ տարածում է գտնում։ Դա ապահովում է ճկունություն՝ ձեր backend-ը կարող է սպասարկել տարբեր հաճախորդներ՝ վեբ, desktop, բջջային, նույնիսկ IoT սարքեր։ Յուրաքանչյուր հաճախորդ կարող է օգտագործել նույն API-ները՝ անկախ ներկայացման շերտից։
Same-Origin Policy և Cross-Origin հարցումներ
Քանի որ հաճախորդն ու սերվերը սովորաբար տարբեր ծրագրեր են, դրանք հիմնականում տեղակայվում են տարբեր տիրույթներում, պորտերում կամ պրոտոկոլներում։ Դա նշանակում է, որ նույնիսկ եթե ձեր սեփական frontend-ը փորձում է կապվել ձեր սեփական backend-ի հետ, զննարկիչը հարցումը կարող է դիտարկել որպես cross-origin։
Սա առավել հաճախ է հանդիպում, երբ աշխատում եք երրորդ կողմի ծառայությունների հետ՝ նույնականացում, անալիտիկա, վճարային համակարգեր և այլն։ Այս բոլոր դեպքերում ձեր frontend-ը պետք է ուղարկի HTTP հարցումներ այլ origin։
Բայց այստեղ է, որ զննարկիչները կիրառում են անվտանգության Same-Origin Policy-ը՝ սահմանափակելով, թե ինչպես կարող են սցենարները (scripts) մի origin-ում փոխազդել ռեսուրսների հետ այլ origin-ներում։ Այստեղ է, որ CORS-ը գործում է՝ ապահովելով անվտանգ տարբերակ cross-origin հարցումների համար։
Ինչու՞ զննարկիչները արգելափակում են Cross-Origin հարցումները
Երբ ձեր վեբ հավելվածը փորձում է հարցում ուղարկել այլ origin-ի, զննարկիչը կիրառում է Same-Origin Policy (SOP) անվանվող անվտանգության քաղաքականություն։ Այն նախատեսված է կանխելու համար, որ վնասակար կայքերը հասանելիություն ստանան այլ կայքերում պահվող տվյալներին առանց թույլտվության։
Պատմականորեն, սա վեբն ավելի ապահով է դարձրել։ Օրինակ, xyz.com-ում աշխատող սցենարը չի կարող գաղտնի ստանալ անձնական տվյալներ abcbank.com-ից։ Բայց SOP-ն նաև խոչընդոտում է օրինական կիրառումները՝ օրինակ, երբ ձեր React հավելվածը localhost:3000-ից փորձում է վերցնել տվյալներ API-ից localhost:8080-ում կամ այլ ծառայությունից։
CORS-ը՝ SOP սահմանափակումների լուծում
Այստեղ է, որ CORS-ը (Cross-Origin Resource Sharing) մտնում է խաղի մեջ։
CORS-ը պրոտոկոլ է, որը թուլացնում է Same-Origin Policy-ն որոշակի վերահսկելի պայմաններում։ Սերվերը հատուկ HTTP վերնագրերի միջոցով կարող է ցույց տալ, որ որոշ cross-origin հարցումներ անվտանգ են և թույլատրելի։
Այսպիսով, երբ ձեր հավելվածը հարցում է ուղարկում այլ origin-ի, սերվերը կարող է պատասխանել հատուկ CORS վերնագրերով, որոնք զննարկչին ասում են․ "Այս cross-origin հարցումը թույլատրված է:" Արդյունքում, զննարկիչը այլևս չի արգելափակում պատասխանը, և ռեսուրսը հասանելի է դառնում։
Ի՞նչ է լինում, երբ CORS-ը միացված է
Երբ զննարկիչը CORS վերնագրերը տեսնում է սերվերի պատասխանում, այն թույլ է տալիս ձեր հավելվածին օգտվել տվյալներից—even եթե հարցումը կատարվել է տարբեր origin-ից։ Սա է CORS-ի իմաստը՝ վերահսկվող մուտք տարբեր origin-ների միջև։
Հիմա, երբ արդեն գիտեք ինչ է CORS-ը և ինչու է պետք, քայլ առ քայլ կանցնենք գործնական օրինակով՝ պարզելու համար, թե ինչպես է այն աշխատում React-ում։
🛠️ Քայլ 1․ Ստեղծեք Express սերվեր API վերջնակետերով
Ցուցադրելու համար՝ ինչպես է աշխատում CORS-ը, մեզ պետք է՝
- 
	
Հաճախորդ (React-ով), որը կկատարի HTTP հարցումներ
 - 
	
Սերվեր (Express-ով), որն ունի API վերջնակետեր
 
⚠️ Իրական CORS սցենար ստանալու համար հաճախորդն ու սերվերը պետք է գործարկվեն տարբեր origin-ներում՝ օրինակ, տարբեր պորտերում (localhost:3000 և localhost:8080)։
🧱 Սերվերի կարգավորում
Սկսենք՝ Express սերվեր ստեղծելով։
- 
	
Ստեղծեք նախագծի պանակը:
 
mkdir cors-server && cd cors-server
- 
	
Նախագիծը նախապատրաստեք Node.js-ով:
 
npm init -y
Սա կստեղծի package.json ֆայլը։
- 
	
Տեղադրեք Express-ը:
 
npm install express
- 
	
Ստեղծեք մուտքային ֆայլ:
 
Ստեղծեք app.js անունով ֆայլ և գրեք՝
const express = require('express');
const app = express();
app.get('/', (req, res) => {
  res.send('Welcome to CORS server 😁');
});
app.get('/cors', (req, res) => {
  res.send('This has CORS enabled 🎈');
});
app.listen(8080, () => {
  console.log('Listening on port 8080');
});
Սա նվազագույն Express սերվեր է երկու վերջնակետով՝ / և /cors։
- 
	
Գործարկեք սերվերը:
 
node app
Այցելեք http://localhost:8080/ զննարկչում՝ տեսնելու համար բարի գալուստ հաղորդագրությունը։ http://localhost:8080/cors-ը ևս աշխատում է։
⚛️ Քայլ 2․ Կարգավորեք React հավելվածը
Այժմ, երբ սերվերը պատրաստ է, ստեղծենք React հավելված՝ HTTP հարցում կատարելու և դիտավորյալ CORS սխալ առաջացնելու համար։
📦 Ստեղծեք նոր React նախագիծ
Սերվերից առանձին պանակում գործարկեք՝
npx create-react-app react-cors-guide
Սա կստեղծի React հավելված react-cors-guide պանակում։ Բացեք src/App.js ֆայլը և փոխարինեք հետևյալով․
import { useEffect } from 'react';
import './App.css';
function App() {
  const makeAPICall = async () => {
    try {
      const response = await fetch('http://localhost:8080/', { mode: 'cors' });
      const data = await response.json();
      console.log({ data });
    } catch (error) {
      console.error('CORS error:', error);
    }
  };
  useEffect(() => {
    makeAPICall();
  }, []);
  return (
    
      React CORS Guide
    
  );
}
export default App;
🧠 Ի՞նչ է տեղի ունենում այստեղ
- 
	
makeAPICallֆունկցիանGETհարցում է կատարումhttp://localhost:8080/հասցեին՝ օգտագործելով Fetch API։ - 
	
{ mode: 'cors' }—բռնացնում է, որ սա cross-origin հարցում է։ - 
	
useEffect-ը հարցումը կատարում է հավելվածի բեռնումից անմիջապես հետո։ 
🔥 Սպասեք CORS սխալի
Եթե գործարկեք React հավելվածը՝
npm start
Զննարկչի կոնսոլում կտեսնեք CORS սխալ՝
Access to fetch at 'http://localhost:8080/' from origin 'http://localhost:3000' has been blocked by CORS policy.
Սա զննարկիչի Same-Origin Policy-ն է, որը արգելափակում է հարցումը։
Բացատրություն CORS սխալի մասին
Այս սխալը առաջանում է, քանի որ, թեև երկուսն էլ աշխատում են localhost-ում, տարբեր պորտերում են (3000 և 8080)՝ տարբեր origin-ներ SOP-ի համար։ Զննարկիչը անվտանգության նկատառումներից ելնելով արգելափակում է հարցումը։
⚠️ Տիպիկ CORS սխալի հաղորդագրություն
Access to fetch at 'http://localhost:8080/' from origin 'http://localhost:3000'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is 
present on the requested resource. If an opaque response serves your needs, 
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
- 
	
Զննարկիչը արգելափակում է պատասխանը, քանի որ սերվերի պատասխանում չկա
Access-Control-Allow-Originվերնագիր։ - 
	
Խորհուրդ է տալիս կիրառել
'no-cors'ռեժիմ, բայց դա վերադարձնում է «անթափանց» (opaque) պատասխան, որը անօգտագործելի է։ - 
	
Կարևոր է․ հաճախորդը սխալ չի արել, սա զննարկչի կանոն է՝ հիմնված սերվերի պատասխանի վրա։
 
✅ CORS-ը միշտ պետք է կարգավորվի սերվերի վրա
Քանի որ հենց սերվերի պատասխանը է որոշում՝ զննարկիչը թույլ կտա՞ տվյալների հասանելիություն, թե ոչ, ճիշտ լուծումը՝ սերվերը պետք է վերադարձնի ճիշտ CORS վերնագրեր։
Կարող եք հաճախորդի կողմից proxy-ներով շրջանցել հարցերը մշակման փուլում, բայց արտադրական միջավայրում CORS-ը պետք է կարգավորել հենց սերվերի վրա։
🔧 Միացրեք CORS-ը Express սերվերում
Վերադարձեք app.js ֆայլին և թարմացրեք /cors վերջնակետը՝
app.get('/cors', (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.send({ msg: 'This has CORS enabled 🎈' });
});
- 
	
Access-Control-Allow-Origin: *նշանակում է՝ ցանկացած origin կարող է օգտվել այս ռեսուրսից։ - 
	
Դեմոնստրացիայի համար սա հարմար է, իսկ արտադրությունում պետք է սահմանափակել։
 
🔁 Թարմացրեք React հաճախորդը
React հավելվածում նոր fetch URL օգտագործեք՝ /cors վերջնակետի համար․
const response = await fetch('http://localhost:8080/cors', { mode: 'cors' });
Պահպանեք փոփոխությունները և վերաբեռնեք dev սերվերը, եթե անհրաժեշտ է։
🧪 Փորձարկեք այն
Զննարկչում թարմացրեք հավելվածը։ Այս անգամ զննարկիչը թույլ կտա պատասխանը, և կոնսոլում կտեսնեք․
{ data: { msg: 'This has CORS enabled 🎈' } }
Հաջողություն է՝ առաջին cross-origin հարցումը ճիշտ CORS կարգավորմամբ։
Հաստատելով լուծումը՝ CORS-ը աշխատում է
Երբ CORS վերնագիրը ճիշտ է տեղադրված սերվերի վրա, սխալն անհետանում է, և ձեր React հավելվածը հաջողությամբ ստանում է JSON պատասխանը։ 🎉 Մի մոռացեք՝ սերվերի վրա կատարած փոփոխությունները ուժի մեջ մտնում են միայն սերվերի վերագործարկումից հետո։
🎯 Սահմանափակեք CORS-ը կոնկրետ origin-ով
* օգտագործելու փոխարեն (թույլ է տալիս բոլորին), կարող եք սահմանափակել միայն օրինակ՝ http://localhost:3000-ով․
app.get('/cors', (req, res) => {
  res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
  res.send({ msg: 'This has CORS enabled 🎈' });
});
Սա խորհուրդ է տրվում արտադրական միջավայրում՝ կանխելու ոչ թույլատրված կայքերի մուտքը ձեր API-ին։
⚠️ Երբ սերվերը փոփոխելու հնարավորություն չունեք
Չնայած ամենաարագ և ապահով տարբերակը սերվերը փոփոխելն է, դա միշտ չէ, որ հնարավոր է։ Հաճախ երրորդ կողմի API-ներ օգտագործելիս այս տարբերակը չկա։
Այդ դեպքում ի՞նչ անել։
🧞♂️ Լուծում․ Proxy React-ում
React-ի մշակման փուլում կարող եք proxy-ով փոխանցել API հարցումները development սերվերի միջոցով։ Սա շրջանցում է զննարկչի SOP-ը՝ հարցումը դարձնելով ներքին։
✏️ Ինչպես կարգավորել proxy
- 
	
React նախագծի
package.json-ում ավելացրեքproxyդաշտ․ 
{
  ...
  "proxy": "http://localhost:8080"
}
- 
	
Վերագործարկեք React dev սերվերը (
npm start)։ Հիմա հարցումները կուղղորդվեն backend-ով։ 
Օրինակ՝
const response = await fetch('/cors');
Սա ներքին կերպով proxy-ով կուղարկվի http://localhost:8080/cors հասցեին։
🧪 Երրորդ կողմի ծառայություն օգտագործե՞լ
{
  ...
  "proxy": "https://randomservice.com"
}
- 
	
Միայն ոչ-HTML հարցումները proxy-ով են անցնում։
 - 
	
Acceptheader-ը չպետք է լինիtext/html։ - 
	
Բարդ դեպքերի համար օգտագործեք http-proxy-middleware։
 
🧹 Ամփոփում՝ React-ում CORS-ի լավագույն փորձը
- 
	
Միշտ փորձեք լուծել CORS-ը սերվերի մակարդակով՝ սա ամենաապահով և վստահելի տարբերակն է։
 - 
	
Մշակման փուլում React-ի proxy-ը կարող է օգնել շրջանցել խնդիրները առանց սերվերի փոփոխման։
 - 
	
Եթե չեք վերահսկում API-ի սերվերը, կապ հաստատեք մատակարարի հետ կամ օգտագործեք ձեր proxy սերվերը։
 - 
	
Օգտագործեք CORS Unblock Chrome ընդլայնումներ միայն ժամանակավոր (և ոչ արտադրական) դեպքերում։
 - 
	
Միշտ նշել
{ mode: 'cors' }ձեր fetch հարցումներում։ - 
	
Հասկանա՛լ, որ զննարկչային շրջանցման տարբերակները արտադրականում չեն աշխատի՝ նախապես մտածեք արտադրական միջավայրի մասին։