🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

كيفية إصلاح خطأ Access-Control-Allow-Origin المفقود في رأس CORS

⏱️2 min read  ·  421 words

الخطألا يوجد رأس “Access-Control-Allow-Origin” على المورد المطلوب هو خطأ CORS الأكثر شيوعًا. هذا يعني أن المتصفح قام بحظر طلبك عبر الأصل لأن الخادم لم يذكر أنه مسموح به. وإليك كيفية إصلاحه بشكل صحيح.

لماذا يحدث هذا

تفرض المتصفحات سياسة المصدر نفسه للأمان — صفحة فيapp.example.com لا يمكن تقديم طلبات بحرية إلىapi.other.com. بالنسبة للطلبات عبر الأصل، يجب أن يتضمن الخادمAccess-Control-Allow-Origin رأس يقول الأصول المسموح بها. إذا كان مفقودًا، فسيقوم المتصفح بحظر الاستجابة ويظهر هذا الخطأ.

النقطة الأساسية: يتم فرض ذلك بواسطة المتصفح ويتم إصلاحه على الخادم. لا يمكن للعميل إضافة هذا الرأس — يجب على الخادم إرساله.

الإصلاح 1: التعبير باستخدام حزمة cors

npm install cors
const cors = require('cors');

// Allow all origins (development only)
app.use(cors());

// ✅ Production: allow specific origin
app.use(cors({
  origin: 'https://app.example.com',
}));

// ✅ Multiple allowed origins
const allowed = ['https://app.example.com', 'https://admin.example.com'];
app.use(cors({
  origin: (origin, callback) => {
    if (!origin || allowed.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  },
}));

الإصلاح 2: الرؤوس اليدوية السريعة

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'https://app.example.com');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');

  // Handle preflight OPTIONS requests
  if (req.method === 'OPTIONS') {
    return res.sendStatus(204);
  }
  next();
});

الإصلاح 3: إنجينكس

location /api/ {
    add_header 'Access-Control-Allow-Origin' 'https://app.example.com' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;

    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' 'https://app.example.com';
        add_header 'Access-Control-Max-Age' 86400;
        return 204;
    }

    proxy_pass http://localhost:3000;
}

الإصلاح 4: مع بيانات الاعتماد (ملفات تعريف الارتباط/المصادقة)

// When sending cookies or auth headers cross-origin:

// Server: exact origin (NOT wildcard) + allow credentials
app.use(cors({
  origin: 'https://app.example.com',   // must be exact, not '*'
  credentials: true,
}));

// Client: include credentials
fetch('https://api.example.com/data', {
  credentials: 'include',
});

// ❌ This combination FAILS:
// origin: '*' with credentials: true
// The browser rejects wildcard origin when credentials are included

بديل وكيل التطوير

// Avoid CORS during development entirely with a dev proxy

// vite.config.ts
export default {
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
      }
    }
  }
};
// Frontend calls /api/... which the dev server proxies to your backend -
// same origin, no CORS. (Production still needs proper CORS headers.)

أخطاء شائعة

// 🐛 Setting CORS headers in BOTH nginx and Express
// Results in duplicate Access-Control-Allow-Origin headers,
// which the browser rejects. Set them in ONE place.

// 🐛 Wildcard with credentials
res.header('Access-Control-Allow-Origin', '*');   // fails with credentials

// 🐛 Forgetting to handle OPTIONS preflight
// PUT/DELETE/JSON requests send a preflight OPTIONS first -
// it must get a valid CORS response too

// 🐛 Trying to fix it in the frontend
// You CANNOT add Access-Control-Allow-Origin from client code -
// it must come from the server

التصحيح

# Check what headers the server actually returns
curl -I -H "Origin: https://app.example.com" https://api.example.com/data

# Look for:
# Access-Control-Allow-Origin: https://app.example.com  ← should be present

# If it's missing, the server isn't configured correctly.
# If it's the wrong origin, fix the server's allowed origins.

الأسئلة المتداولة

س: لماذا لا يمكنني إصلاح ذلك في كود الواجهة الأمامية الخاص بي؟
ج: يتم فرض CORS بواسطة المتصفح ويتم التحكم فيها بواسطة الخادم.Access-Control-Allow-Origin يجب أن يأتي الرأس من الخادم الذي يستجيب للطلب. لا يمكن لأي قدر من كود الواجهة الأمامية إضافته – يجب عليك تكوين الخادم (أو استخدام وكيل).

س: لماذا يعمل في Postman وليس في المتصفح؟
ج: يتم فرض CORS بواسطة المتصفحات فقط. يقوم ساعي البريد وcurl بتقديم الطلبات مباشرة دون فحص CORS للمتصفح. يؤكد هذا أن الخادم الخاص بك يعمل، كل ما عليك فعله هو إضافة رؤوس CORS لعملاء المتصفح.

س: هل يجب أن أستخدم Access-Control-Allow-Origin: *؟
ج: فقط لواجهات برمجة التطبيقات العامة حقًا التي لا تحتوي على بيانات اعتماد. بالنسبة لأي شيء يحتوي على مصادقة أو ملفات تعريف الارتباط، يجب عليك تحديد أصول دقيقة (يفشل حرف البدل مع بيانات الاعتماد). يعد تحديد الأصول الدقيقة أيضًا أكثر أمانًا — لا تستخدم* في الإنتاج لواجهات برمجة التطبيقات المصادق عليها.

س: أين يجب أن أقوم بتعيين رؤوس CORS — nginx أم التطبيق؟
ج: مكان واحد فقط. إذا قمت بتعيينها في كل من nginx وتطبيقك، فستحصل على رؤوس مكررة، والتي ترفضها المتصفحات. اختر طبقة واحدة (عادةً التطبيق للمرونة، أو nginx إذا كان لديك وكيل عكسي) وقم بتكوين CORS هناك.

س: لماذا يعمل POST الخاص بي ولكن يفشل PUT؟
ج: يؤدي PUT/DELETE والطلبات التي تحتوي على أجسام JSON أو الرؤوس المخصصة إلى تشغيل طلب OPTIONS للاختبار المبدئي. يجب أن يستجيب خادمك لـ OPTIONS برؤوس CORS صالحة أيضًا. تأكد من أن تكوين CORS الخاص بك يتعامل مع طريقة OPTIONS، وليس فقط GET/POST.

الخلاصة

“لا يوجد رأس ‘Access-Control-Allow-Origin’ موجود” يعني أن الخادم لم يخبر المتصفح بأن طلبك عبر الأصل مسموح به. الإصلاح موجود دائمًا على الخادم:أضفAccess-Control-Allow-Origin الرأس عبر حزمة cors (Express)، أو الرؤوس اليدوية، أو تكوين nginx، مع تحديد الأصول الدقيقة (مطلوب عند استخدام بيانات الاعتماد). تعامل مع طلبات الاختبار المبدئي لـ OPTIONS، وقم بتعيين CORS في طبقة واحدة فقط لتجنب التكرارات، وتذكر أنه لا يمكنك إصلاحها من كود الواجهة الأمامية. من أجل التطوير، يتجنب وكيل خادم التطوير CORS تمامًا – ولكن الإنتاج يحتاج دائمًا إلى رؤوس CORS المناسبة من جانب الخادم.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা