CORS خرابیاں کیسے ٹھیک کریں (اور یہ کیوں آتی ہیں)
CORS خرابی کا مطلب ہے کہ آپ کے ویب صفحے نے کسی دوسرے origin (کسی اور ڈومین، پورٹ یا پروٹوکول) سے جواب پڑھنے کی کوشش کی، اور اس سرور نے ایسے headers نہیں بھیجے جو کہیں کہ یہ جائز ہے۔ براؤزر صارفین کی حفاظت کے لیے جواب کو روک دیتے ہیں۔ آپ اسے سرور پر ٹھیک کرتے ہیں، یعنی اپنی سائٹ کے origin کے لیے Access-Control-Allow-Origin header واپس کر کے اور OPTIONS preflight درخواستوں کو سنبھال کر، یا درخواست اپنے بیک اینڈ کے ذریعے، اسی origin پر بھیج کر اس سے بچ کر۔
یہ ویب ڈیولپمنٹ کی سب سے الجھن والی خرابیوں میں سے ایک ہے، کیونکہ درخواست اکثر سرور تک ٹھیک پہنچ جاتی ہے۔ یہ گائیڈ بتاتی ہے کہ کیا ہو رہا ہے اور ہر قسم کو کیسے ٹھیک کرنا ہے۔
"origin" کا مطلب
origin پروٹوکول، ڈومین اور پورٹ کا مجموعہ ہے:
| URL | Origin |
|---|---|
https://myapp.com/dashboard | https://myapp.com |
https://api.myapp.com/users | https://api.myapp.com (مختلف سب ڈومین، اس لیے مختلف origin) |
http://localhost:5173 | http://localhost:5173 |
http://localhost:3000 | http://localhost:3000 (مختلف پورٹ، اس لیے مختلف origin) |
براؤزر same-origin policy پر عمل کرتے ہیں: کسی صفحے کا JavaScript اپنے origin کے جوابات آزادانہ پڑھ سکتا ہے، مگر دوسروں کے نہیں۔ CORS (Cross-Origin Resource Sharing) وہ نظام ہے جس میں سرور خود اجازت دیتا ہے: "میرے جوابات ان origins کے صفحات پڑھ سکتے ہیں۔"
دو نتائج لوگوں کو حیران کرتے ہیں:
- درخواست اکثر سرور تک پہنچ جاتی ہے۔ CORS عموماً آپ کے کوڈ کو جواب پڑھنے سے روکتا ہے، سرور کو درخواست وصول کرنے سے نہیں۔ ایک POST محفوظ ہو چکی ہو سکتی ہے حالانکہ آپ کو خرابی نظر آئی۔
- صرف براؤزر اسے نافذ کرتے ہیں۔ curl، Postman اور سرور سائیڈ کوڈ CORS کو بالکل نظر انداز کرتے ہیں۔ اسی لیے "Postman میں کام کرتا ہے" CORS کے بارے میں کچھ نہیں بتاتا۔
مرحلہ 1: درست خرابی پڑھیں
ڈویلپر ٹولز کھولیں (دائیں کلک → Inspect)، Console پر جائیں، اور پورا پیغام پڑھیں۔ Chrome کے الفاظ بتاتے ہیں کہ مسئلہ کیا ہے:
| پیغام میں یہ ہو | کیا غلط ہے |
|---|---|
No 'Access-Control-Allow-Origin' header is present | سرور نے header بالکل نہیں بھیجا، یا درخواست آپ کے CORS کوڈ تک پہنچنے سے پہلے ناکام ہو گئی (مثلاً 404 یا 500) |
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied origin | سرور آپ کے علاوہ کسی اور 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' | آپ cookies بھیج رہے ہیں، اور سرور نے * کے ساتھ جواب دیا |
Request header field authorization is not allowed | سرور نے وہ header Access-Control-Allow-Headers میں درج نہیں کیا |
پھر Network ٹیب کھولیں، ناکام درخواست (اور اس سے پہلے کوئی OPTIONS درخواست) تلاش کریں، اور اس کا اسٹیٹس کوڈ اور جواب کے headers دیکھیں۔
پہلے اسٹیٹس کوڈ چیک کریں۔ بہت سی "CORS خرابیاں" دراصل چھپی ہوئی سرور خرابیاں ہوتی ہیں۔ اگر سرور کریش ہو یا 404 دے تو اس کے خرابی کے جواب میں اکثر CORS headers نہیں ہوتے، اس لیے براؤزر اصل مسئلے کے بجائے CORS بتاتا ہے۔ 500 یا 404 ٹھیک کریں، اور CORS خرابی غائب ہو سکتی ہے۔
مرحلہ 2: طے کریں کہ کیا براؤزر سے اس API کو کال کرنا چاہیے بھی
headers شامل کرنے سے پہلے پوچھیں: کیا براؤزر کو اس API کو براہ راست کال کرنا چاہیے؟
- کوئی تیسری پارٹی API جسے secret key چاہیے (OpenAI، Stripe کی secret key، زیادہ تر ای میل سروسز) کو کبھی براؤزر سے کال نہیں کرنا چاہیے۔ key ہر زائر کو نظر آ جائے گی۔ اسے اپنے بیک اینڈ سے کال کریں، اور CORS کا مسئلہ ختم ہو جاتا ہے، کیونکہ سرور سے سرور کی درخواستوں پر CORS لاگو نہیں ہوتا۔ دیکھیں API keys کو محفوظ کیسے رکھیں۔
- کوئی تیسری پارٹی API جو آپ کے کنٹرول میں نہیں اور CORS headers نہیں بھیجتی، اسے آپ کی طرف سے ٹھیک نہیں کیا جا سکتا۔ اسے اپنے بیک اینڈ سے کال کریں۔
- آپ کی اپنی API کو درست ترتیب دے کر ٹھیک کیا جا سکتا ہے۔ نیچے دیکھیں۔
مرحلہ 3: اپنے سرور پر ٹھیک کریں
سرور کو اپنے جوابات میں درست headers شامل کرنے ہوں گے، بشمول خرابی کے جوابات۔
اصل درخواست کے لیے بھیجیں:
Access-Control-Allow-Origin: https://myapp.com(آپ کے frontend کا عین origin، آخر میں slash کے بغیر)Vary: Origin، اگر قدر اس پر منحصر ہو کہ کس 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(ہر وہ custom header جو آپ بھیجتے ہیں)- اختیاری طور پر
Access-Control-Max-Age: 600، تاکہ براؤزر preflight کو کچھ دیر کیش کرے
زیادہ تر فریم ورکس میں یہ کام کرنے کا package یا ترتیب ہوتی ہے۔ 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 کو اپنے راستوں اور authentication سے پہلے رکھیں، تاکہ preflight درخواستیں (جن میں لاگ ان نہیں ہوتا) 401 کے ساتھ رد نہ ہوں۔
AI بلڈر کے ساتھ سیٹ اپ کو درست طور پر بیان کریں:
https://myapp.comپر frontend،https://api.myapp.comپر API کو کال کرتا ہے اور "Response to preflight request doesn't pass access control check" آتا ہے۔ API پر CORS ترتیب دیں تاکہ بالکلhttps://myapp.comاور پریویو origin کی اجازت ہو، Content-Type اور Authorization headers کے ساتھ GET، POST، PATCH، DELETE کی اجازت ہو، OPTIONS کو auth سے پہلے سنبھالا جائے، اور خرابی کے جوابات میں بھی CORS headers شامل ہوں۔
مرحلہ 4: cookies اور credentials سنبھالیں
اگر آپ کا frontend کسی دوسرے origin کو cookies (مثلاً لاگ ان سیشن) بھیجتا ہے، تو دونوں طرف کو متفق ہونا ہوگا:
- frontend
fetchپرcredentials: "include"لگاتا ہے، یا axios میںwithCredentials: true۔ - سرور
Access-Control-Allow-Credentials: trueبھیجتا ہے۔ - سرور کا
Access-Control-Allow-Originعین origin ہونا چاہیے،*نہیں۔
کراس سائٹ cookies کو cookie پر SameSite=None; Secure بھی چاہیے، اور کچھ براؤزر تیسری پارٹی cookies کو مزید محدود کرتے ہیں۔ یہ مرحلہ 5 کے طریقے کو ترجیح دینے کی ایک اور وجہ ہے۔
مرحلہ 5: same-origin سیٹ اپ سے CORS سے بچیں
اکثر سب سے صاف حل یہ ہے کہ کراس origin درخواستیں بالکل نہ کی جائیں۔ API کو اسی origin سے پیش کریں جہاں صفحہ ہے، مثلاً https://myapp.com/api/... پر:
- ڈیولپمنٹ میں زیادہ تر ڈیولپ سرورز proxy کر سکتے ہیں۔ Vite کی
server.proxyترتیب/apiکو دوسرے پورٹ پر آپ کے بیک اینڈ کی طرف بھیج سکتی ہے، تاکہ براؤزر صرف ایک origin سے بات کرے۔ - پروڈکشن میں اپنے ہوسٹ کی rewrite یا proxy ترتیبات کے ذریعے
/apiکو بیک اینڈ کی طرف روٹ کریں، یا frontend اور API ایک ہی سرور سے پیش کریں۔
پھر frontend fetch("/api/orders") جیسا relative راستہ کال کرتا ہے۔ کوئی کراس origin درخواست نہیں، کوئی origins کے پار preflight نہیں، اور cookies کی پریشانی نہیں۔ اس کا مطلب یہ بھی ہے کہ آپ کوئی ایسا API ڈومین ہارڈ کوڈ نہیں کرتے جو پریویو اور پروڈکشن میں مختلف ہو۔
frontend کو مکمل URL کے بجائے relative /api راستوں سے بیک اینڈ کال کرنے کے لیے بدلیں، اور ایک ڈیولپمنٹ proxy سیٹ کریں تاکہ /api، API سرور کی طرف آگے بڑھے۔ پھر وہ CORS ترتیبات ہٹا دیں جن کی اب ضرورت نہیں۔
کیا نہ کریں
fetchمیںmode: "no-cors"۔ یہ کچھ بائی پاس نہیں کرتا؛ یہ آپ کے کوڈ کو ایک خالی، ناقابلِ پڑھائی جواب دیتا ہے۔- CORS بند کرنے والی براؤزر ایکسٹینشنز۔ یہ صرف آپ کا براؤزر بدلتی ہیں۔ ہر زائر کو پھر بھی خرابی نظر آتی ہے۔
- حقیقی ایپس کے لیے عوامی "CORS proxy" سروسز۔ یہ ان کے ذریعے گزرنے والی ہر چیز پڑھ اور بدل سکتی ہیں، اور یہ بند بھی ہو جاتی ہیں۔
- لاگ ان استعمال کرنے والی API پر
Access-Control-Allow-Origin: *۔ یہ credentials کے ساتھ ویسے بھی کام نہیں کرتا، اور نجی ڈیٹا کے لیے غلط ڈیفالٹ ہے۔ - کسی بھی
Originheader کو واپس منعکس کرنا جب credentials کی اجازت ہو۔ اس سے کوئی بھی ویب سائٹ آپ کے صارفین کی طرف سے لاگ ان درخواستیں کر سکتی ہے۔ اجازت کی فہرست (allowlist) استعمال کریں۔
AI سے بنی ایپس میں عام وجوہات
| صورتحال | حل |
|---|---|
| frontend secret key کے ساتھ کسی تیسری پارٹی API کو کال کرتا ہے | کال کو بیک اینڈ پر منتقل کریں |
| پریویو میں کام کرتا ہے، شائع شدہ ڈومین پر ناکام | شائع شدہ اور کسٹم ڈومین کے origins اجازت کی فہرست میں شامل کریں، یا relative /api راستے استعمال کریں |
| خرابی صرف POST، PUT یا DELETE پر | preflight سنبھالی نہیں گئی؛ OPTIONS ہینڈلنگ اور اجازت شدہ headers شامل کریں |
| لاگ ان شامل کرنے کے بعد خرابی آئی | credentials کو عین origin اور Allow-Credentials چاہیے |
| "CORS خرابی" مگر Network ٹیب میں 500 | پہلے سرور کی خرابی ٹھیک کریں |
API URL localhost پر ہارڈ کوڈ | relative راستے یا ماحول کے مطابق ترتیب استعمال کریں |
Mythex میں CORS
جب کسی Mythex پروجیکٹ میں ویب سائٹ اور API سرور ہوں، تو دونوں ایک ہی پروجیکٹ میں سروسز کے طور پر چلتے ہیں، اور آپ پریویو میں ان کے درمیان بدل سکتے ہیں۔ ایجنٹ سے کہیں کہ frontend بیک اینڈ کو relative /api راستے سے کال کرے، جو ڈیولپمنٹ میں proxy ہو، تو زیادہ تر CORS مسائل سے بچ جاتے ہیں۔ اگر واقعی کراس origin کالز درکار ہوں تو ایجنٹ کو کنسول کی درست خرابی اور متعلقہ origins دیں۔ شائع شدہ ایپ پر بھی نتیجہ چیک کریں، کیونکہ اس کا پتہ پریویو سے مختلف ہے۔ دستاویزات میں Multi-service apps اور API backends دیکھیں، اور ہماری گائیڈز AI سے بنی ایپ کی ڈیبگنگ اور frontend بمقابلہ backend۔
CORS چیک لسٹ
- کنسول کی پوری خرابی اور ناکام درخواست کا اسٹیٹس کوڈ پڑھا
- چھپا ہوا 404 یا 500 خارج کیا
- secret-key والی APIs بیک اینڈ سے کال ہوتی ہیں، براؤزر سے نہیں
- سرور
Access-Control-Allow-Originعین اجازت شدہ origins کے ساتھ بھیجتا ہے -
OPTIONSpreflight کا جواب اجازت شدہ methods اور headers کے ساتھ، auth سے پہلے دیا جاتا ہے - خرابی کے جوابات میں بھی CORS headers موجود ہیں
- credentials: عین origin،
Allow-Credentials: true، درست cookie ترتیبات - پریویو، شائع شدہ اور کسٹم ڈومین کے origins سب شامل ہیں، یا relative
/apiراستے استعمال ہوئے -
no-cors، عوامی proxies، یا کسی بھی origin کو منعکس کرنے کے شارٹ کٹس نہیں
سوالات
CORS خرابی کا کیا مطلب ہے؟
آپ کا صفحہ ایک origin سے لوڈ ہوا اور کسی دوسرے origin کا جواب پڑھنے کی کوشش کی، اور اس سرور کے جواب میں ایسے headers نہیں تھے جو اس کی اجازت دیں۔ براؤزر آپ کے کوڈ کو جواب پڑھنے سے روکتا ہے۔ حل سرور پر ہے، یا درخواست کے راستے میں، frontend کوڈ میں نہیں۔
کیا میں CORS خرابی frontend سے ٹھیک کر سکتا ہوں؟
صحیح معنوں میں نہیں۔ mode: 'no-cors' جیسی ترتیبات صرف جواب کو آپ کے کوڈ سے چھپاتی ہیں۔ آپ سرور کو درست Access-Control-Allow-Origin header بھیجنے پر لگا کر، یا اپنے بیک اینڈ یا same-origin proxy کے ذریعے API کو کال کر کے اسے ٹھیک کرتے ہیں۔
کیا Access-Control-Allow-Origin: * محفوظ ہے؟
عوامی ڈیٹا کے لیے ٹھیک ہے جسے کوئی بھی پڑھ سکتا ہو، جیسے بغیر لاگ ان کی عوامی API۔ اسے cookies یا دوسری credentials کے ساتھ استعمال نہیں کیا جا سکتا، اور نجی APIs کے لیے آپ کو وہ عین origins لکھنے چاہئیں جن کی اجازت ہے۔
میری درخواست Postman یا curl میں کام کرتی ہے مگر براؤزر میں کیوں نہیں؟
CORS صرف براؤزرز نافذ کرتے ہیں۔ Postman اور curl جیسے ٹولز اسے لاگو نہیں کرتے، اس لیے درخواست وہاں کامیاب ہو سکتی ہے اور جب صفحے کا JavaScript اسے بھیجے تو پھر بھی روک دی جائے۔
preflight درخواست کیا ہوتی ہے؟
ان درخواستوں کے لیے جو سادہ نہیں ہوتیں، جیسے JSON POST یا Authorization header والی درخواست، براؤزر پہلے ایک OPTIONS درخواست بھیجتا ہے اور پوچھتا ہے کہ کون سے methods اور headers کی اجازت ہے۔ اگر وہ OPTIONS درخواست ناکام ہو یا درست headers نہ ہوں، تو اصل درخواست بھیجی ہی نہیں جاتی۔