حل مشاكل الـ 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؟
تواصل
معنا للمساعدة