CORS Hatası Nedir? Node.js, Express, React, Next.js ve Laravel'de CORS Çözüm Rehberi
Modern web geliştirmede frontend (React, Vue, Next.js) ve backend (Node.js, Express, Laravel, Python) uygulamalarını farklı alan adları veya portlar üzerinde çalıştırırken karşılaşılan en yaygın engel CORS (Cross-Origin Resource Sharing) hatasıdır. Bu rehberde CORS mekanizmasını, Preflight (OPTIONS) isteklerinin mantığını ve farklı framework'lerde kesin çözüm adımlarını inceleyeceğiz.
📌 Bu Rehberde Ne Öğreneceksiniz?
- • CORS (Cross-Origin Resource Sharing) nedir ve neden oluşur?
- • Preflight (OPTIONS) isteği nedir? "Header ekledim ama çalışmıyor" çözümü
- • Node.js / Express.js projelerinde CORS çözümü
- • Next.js (App Router & Route.js) API CORS ayarları
- • Laravel (cors.php & Sanctum) ortam yapılandırması
- • Skyversal PaaS üzerinde Edge Proxy CORS yönetimi
Adım 1 — CORS Hatası Nedir ve Neden Oluşur?
💡 Özet Cevap: CORS (Cross-Origin Resource Sharing), bir web tarayıcısının güvenlik nedeniyle farklı bir kök adresten (origin) gelen API isteklerini engellemesidir. Sunucu yanıtında Access-Control-Allow-Origin başlığı (header) yer almadığında tarayıcı isteği engeller.
Aynı Kök Politikası (Same-Origin Policy - SOP) gereği, protokolu (http/https), alan adı (domain) veya port numarası farklı olan iki adres arasındaki istemci (client) istekleri varsayılan olarak engellenir. Örneğin http://localhost:3000 adresindeki React uygulamanız http://localhost:5000 adresindeki Node.js backend servisinize istek attığında tarayıcınız isteği durdurur.
Adım 2 — "Header Ekledim Ama Hata Sürüyor": Preflight (OPTIONS) İsteği Çözümü
💡 Kritik Teşhis: İsteğinizde Authorization (Bearer token), Content-Type: application/json veya PUT/DELETE yöntemleri varsa, tarayıcı asıl istekten önce sunucuya otomatik bir HTTP OPTIONS (Preflight) ön kontrol isteği gönderir. Sunucu bu OPTIONS isteğine HTTP 200 OK veya 204 No Content dönmezse CORS hatası devam eder.
Access-Control-Allow-Origin: https://siteniz.com(veya *)Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONSAccess-Control-Allow-Headers: Content-Type, Authorization, X-Requested-WithAccess-Control-Max-Age: 86400(Preflight sonucunu 24 saat önbellekler)
Adım 3 — Node.js & Express.js İle CORS Çözümü
💡 Kod Çözümü: Express.js ortamında resmi cors middleware paketi hem standart yanıt başlıklarını hem de OPTIONS Preflight isteklerini otomatik olarak yönetir.
# Terminal üzerinden cors eklentisini yükleyin: npm install cors
Express uygulamanızın ana giriş dosyasına (server.js veya app.js) aşağıdaki yapılandırmayı ekleyin:
const express = require('express'); const cors = require('cors'); const app = express(); // İzin verilen kök adresler (Production & Local React/Vue/Next) const allowedOrigins = [ 'https://siteniz.com', 'https://app.siteniz.com', 'http://localhost:3000' ]; app.use(cors({ origin: function (origin, callback) { if (!origin || allowedOrigins.indexOf(origin) !== -1) { callback(null, true); } else { callback(new Error('CORS Politikası Tarafından Engellendi')); } }, credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'] }));
Adım 4 — Next.js (next.config.js & App Router route.ts) CORS Ayarları
💡 Mimarisi: Next.js projelerinde CORS başlıklarını global olarak next.config.js dosyasından tanımlayabileceğiniz gibi, App Router (app/api/[...route]/route.ts) rotalarında doğrudan OPTIONS handler'ı dışa aktararak da yönetebilirsiniz.
Seçenek A: Global Yapılandırma (next.config.js):
// next.config.js module.exports = { async headers() { return [ { source: "/api/:path*", headers: [ { key: "Access-Control-Allow-Credentials", value: "true" }, { key: "Access-Control-Allow-Origin", value: "https://siteniz.com" }, { key: "Access-Control-Allow-Methods", value: "GET,DELETE,PATCH,POST,PUT,OPTIONS" }, { key: "Access-Control-Allow-Headers", value: "X-CSRF-Token, X-Requested-With, Accept, Content-Type, Authorization" }, ] } ] } };
Seçenek B: Next.js App Router Özel OPTIONS Handler (app/api/data/route.ts):
// app/api/data/route.ts export async function OPTIONS(request: Request) { return new Response(null, { status: 204, headers: { 'Access-Control-Allow-Origin': 'https://siteniz.com', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, }); }
Adım 5 — Laravel (config/cors.php & Sanctum) Yapılandırması
💡 Çözüm Yolu: Laravel 9+ sürümlerinde CORS ayarları config/cors.php dosyasındaki allowed_origins ve supports_credentials değerleri düzenlenerek sıfır hatayla çalışır.
// config/cors.php return [ 'paths' => ['api/*', 'sanctum/csrf-cookie'], 'allowed_methods' => ['*'], 'allowed_origins' => [ 'https://siteniz.com', 'http://localhost:3000' ], 'allowed_headers' => ['*'], 'supports_credentials' => true, ];
Skyversal PaaS üzerinde mikroservislerinizi ve React/Next/Vue frontend uygulamalarınızı aynı proje altında barındırdığınızda, Edge Gateway otomatik olarak iç rotalama yapar ve ekstra CORS karmaşası yaşamadan güvenli canlı yayın sağlar.