CORS للمبتدئ: ليه المتصفح بيرفض طلب الـ API بتاعك وإزاي تصلّحه صح
لو الـ fetch بيطلعلك خطأ أحمر في الكونسول فيه كلمة CORS، ركّز في نقطة واحدة: المشكلة مش في كودك، ومش في السيرفر بيقع. الطلب بيوصل السيرفر فعلاً، والسيرفر بيرد عادي. اللي بيحصل إن المتصفح نفسه بيرفض إنه يسلّمك الرد، لأنه بيحميك. في المقال ده هتفهم ليه بيعمل كده، وتصلّحها صح بترويسة واحدة من السيرفر.
المشكلة باختصار
عندك فرونت إند شغّال على https://app.example.com، وبيكلّم API على https://api.example.com. تفتح الكونسول تلاقي رسالة زي دي:
Access to fetch at 'https://api.example.com/orders' from origin
'https://app.example.com' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.الرسالة واضحة أكتر مما تفتكر: السيرفر ما بعتش ترويسة اسمها Access-Control-Allow-Origin، فالمتصفح قرر يمنعك من قراءة الرد. الافتراض هنا إن الفرونت والـ API على أصلين مختلفين (origins مختلفة). لو الاتنين على نفس النطاق، المشكلة دي مش بتظهر أصلاً.
الفكرة بمثال: حارس مبنى الشركة
تخيّل شركة في مبنى فيه حارس على الباب. الحارس عنده قاعدة بسيطة: أي حد جاي من نفس المبنى يعدّي على طول. لكن أي زائر جاي من مبنى تاني، الحارس بيوقفه ويسأل الإدارة الأول: «فيه واحد جاي من مبنى app عايز يدخل ويعمل كذا، تسمحوا؟». لو الإدارة قالت «آه، اسمه في القائمة»، يعدّيه. لو مردّتش أو قالت لأ، يرجّعه من غير ما يدخل.
المتصفح هو الحارس. مبناك (موقعك) هو «نفس المبنى». والـ API اللي على نطاق تاني هو «المبنى التاني». الحارس مش بيمنعك عشان يزعجك، بيمنعك عشان لو موقع خبيث فتحته بالغلط حاول يكلّم بنك أونلاين انت مسجّل فيه، الحارس يوقفه قبل ما يسرق بياناتك.
الشرح العلمي: سياسة نفس الأصل (Same-Origin Policy)
«الأصل» (Origin) مش الدومين بس. هو تلات حاجات مع بعض: البروتوكول + الاستضافة + المنفذ. يعني https://app.example.com أصل مختلف تمامًا عن http://app.example.com (بروتوكول مختلف)، وعن https://api.example.com (استضافة مختلفة)، وعن https://app.example.com:8080 (منفذ مختلف).
المتصفح بيطبّق قاعدة اسمها Same-Origin Policy: كود جافاسكريبت في صفحة من أصل معيّن، ممنوع يقرا رد طلب رايح لأصل تاني، إلا لو الأصل التاني صرّح بوضوح إنه موافق. التصريح ده بيتم عن طريق ترويسات CORS في رد السيرفر. يعني CORS مش «حماية» بتضيفها، هو من قاعدة المنع الافتراضية.