حل مشاكل الـ CORS عند تطوير واجهات برمجة التطبيقات (APIs)

تاريخ النشر: 15 فبراير 2026 | القراءة: 7 دقائق

ما هو خطأ CORS؟

إذا كنت مطوراً، فقد واجهت هذا الخطأ المزعج:

Access to fetch at 'https://api.example.com' from origin 
'https://mywebsite.com' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the 
requested resource.

CORS (Cross-Origin Resource Sharing) هو آلية أمان في المتصفحات تمنع موقعاً من طلب موارد من domain مختلف.

لماذا يوجد CORS أصلاً؟

السيناريو الخطير (بدون CORS)

1. تفتح موقعك البنكي: bank.com
2. في تاب آخر، تفتح موقع ضار: evil.com
3. evil.com يُرسل طلب لـ bank.com/transfer (سرقة أموالك!)
4. بدون CORS، الطلب ينجح! 💀

مع CORS (الحماية)

المتصفح يمنع evil.com من الوصول لـ bank.com ما لم يسمح البنك صراحةً (عبر Headers).

متى تحدث مشكلة CORS؟

أمثلة

  • موقعك: https://mysite.com يطلب بيانات من https://api.example.com
  • موقعك على localhost:3000 يطلب من localhost:5000 (نعم، حتى البورت المختلف!)
  • موقعك http://mysite.com يطلب من https://mysite.com (HTTP ≠ HTTPS)

⚠️ ملاحظة: CORS لا يحدث في الـ Backend (Node.js, Python). إنه محدود بالمتصفحات فقط!

الحل 1: إعداد CORS في الـ Backend

Node.js / Express

const express = require('express');
const cors = require('cors');
const app = express();

// السماح لكل الـ Origins (التطوير فقط!)
app.use(cors());

// أو السماح لـ domain محدد (الإنتاج)
app.use(cors({
  origin: 'https://mywebsite.com'
}));

app.get('/api/data', (req, res) => {
  res.json({ message: 'Success!' });
});

app.listen(5000);

Python / Flask

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)

# السماح لكل الـ Origins
CORS(app)

# أو لـ domain محدد
CORS(app, resources={r"/api/*": {"origins": "https://mywebsite.com"}})

@app.route('/api/data')
def get_data():
    return {'message': 'Success!'}

PHP

<?php
// في أول ملف API
header("Access-Control-Allow-Origin: https://mywebsite.com");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type");

// باقي كودك
echo json_encode(['message' => 'Success!']);
?>

الحل 2: Proxy في الـ Frontend (للتطوير)

React / Vite

في vite.config.js:

export default {
  server: {
    proxy: {
      '/api': {
        target: 'https://api.example.com',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
}

الآن يمكنك:

// بدلاً من:
fetch('https://api.example.com/data')

// استخدم:
fetch('/api/data') // Vite سيوجهه تلقائياً

الحل 3: استخدام خدمة Proxy خارجية

للتطوير السريع

  • cors-anywhere: https://cors-anywhere.herokuapp.com/
  • allorigins: https://api.allorigins.win/raw?url=
// ⚠️ للتطوير فقط - لا تستخدم في الإنتاج!
fetch('https://cors-anywhere.herokuapp.com/https://api.example.com/data')
  .then(res => res.json())
  .then(data => console.log(data));

تحذير: لا تستخدم Proxies عامة في الإنتاج (خطر أمني + بطء)!

الحل 4: Headers يدوياً (للطلبات المعقدة)

Preflight Requests

للطلبات من نوع PUT, DELETE، أو مع Headers مخصصة، المتصفح يُرسل طلب OPTIONS أولاً للتأكد.

Node.js - التعامل مع OPTIONS

app.options('*', cors()); // لكل الـ OPTIONS requests

app.post('/api/data', cors(), (req, res) => {
  res.json({ message: 'Success!' });
});

Headers الكاملة

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'https://mywebsite.com');
  res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization');
  res.header('Access-Control-Allow-Credentials', 'true');
  
  if (req.method === 'OPTIONS') {
    return res.sendStatus(200);
  }
  next();
});

الأسئلة الشائعة

❓ لماذا يعمل في Postman لكن لا يعمل في المتصفح؟

Postman ليس متصفحاً! CORS آلية خاصة بالمتصفحات فقط. Postman, curl, وأدوات API الأخرى تتجاهلها.

❓ هل `Access-Control-Allow-Origin: *` آمن؟

لا! للتطوير فقط. في الإنتاج، حدد الـ domains المسموحة بدقة.

❓ كيف أسمح لأكثر من domain؟

const allowedOrigins = [
  'https://mysite.com',
  'https://myapp.com'
];

app.use(cors({
  origin: (origin, callback) => {
    if (allowedOrigins.includes(origin) || !origin) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  }
}));

❓ CORS في Next.js؟

في next.config.js:

module.exports = {
  async headers() {
    return [
      {
        source: '/api/:path*',
        headers: [
          { key: 'Access-Control-Allow-Origin', value: '*' },
          { key: 'Access-Control-Allow-Methods', value: 'GET,POST,PUT,DELETE' },
        ],
      },
    ];
  },
};

الخلاصة: أفضل الممارسات

  • للتطوير: استخدم cors() بدون قيود
  • للإنتاج: حدد الـ origins المسموحة بدقة
  • مع Credentials: لا تستخدم *، حدد origin دقيق
  • ✅ تعامل مع OPTIONS requests صح
  • ❌ لا تستخدم Proxies عامة في الإنتاج
  • ❌ لا تعطل CORS في المتصفح (خطر أمني!)

تواجه مشاكل في تطوير الـ API؟
تواصل معنا للمساعدة