SavefileArchive
USD/IDR ...
|
BTC ...
|
ETH ...
|
GOLD/gram ...
Terbaru
SavefileArchive — Tutorial coding, tips programming, dan dunia musik untuk developer & pecinta musik Indonesia
CORS Error: Penyebab, Cara Fix, dan Cara Mencegahnya Selamanya

CORS Error: Penyebab, Cara Fix, dan Cara Mencegahnya Selamanya

CORS Error: Penyebab, Cara Fix, dan Cara Mencegahnya Selamanya

Ilustrasi CORS Error

Kamu baru saja selesai bikin frontend React yang memanggil API backend. Buka browser, cek console — dan langsung disambut pesan merah yang menyebalkan:

Access to fetch at 'http://localhost:3001/api/users' from origin 
'http://localhost:3000' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

CORS error adalah salah satu error paling sering dialami developer web, terutama yang baru mulai memisahkan frontend dan backend. Kabar baiknya: begitu kamu paham cara kerjanya, kamu tidak akan bingung lagi.


1. Apa Itu CORS dan Kenapa Browser Memblokir Request?

CORS (Cross-Origin Resource Sharing) adalah mekanisme keamanan browser yang membatasi halaman web untuk membuat request ke domain yang berbeda dari tempat halaman itu dimuat.

Origin terdiri dari tiga komponen: protokol + domain + port. Jika salah satu berbeda, itu dianggap cross-origin:

http://localhost:3000  →  http://localhost:3001   ❌ port berbeda
http://localhost:3000  →  https://localhost:3000  ❌ protokol berbeda
http://localhost:3000  →  http://myapi.com        ❌ domain berbeda
http://localhost:3000  →  http://localhost:3000   ✅ sama persis

Penting: CORS adalah kebijakan browser, bukan server. Server tetap menerima dan memproses request — browser yang memblokir response-nya dari JavaScript. Itulah kenapa request dari Postman atau curl selalu berhasil meski CORS belum dikonfigurasi.


2. Fix CORS di Berbagai Backend

Node.js + Express

// Install: npm install cors
import cors from 'cors';

// ✅ Development: izinkan semua origin (JANGAN di production!)
app.use(cors());

// ✅ Production: izinkan origin spesifik
app.use(cors({
  origin: [
    'https://aplikasikita.com',
    'https://www.aplikasikita.com',
  ],
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,  // Wajib jika pakai cookies atau Authorization header
}));

// ✅ Dynamic origin (untuk multi-tenant atau staging environment)
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') || [];

app.use(cors({
  origin: (origin, callback) => {
    // Izinkan request tanpa origin (Postman, server-to-server)
    if (!origin) return callback(null, true);
    
    if (allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error(`Origin ${origin} tidak diizinkan`));
    }
  },
  credentials: true,
}));

Python + FastAPI

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://aplikasikita.com"],  # atau ["*"] untuk dev
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

Python + Django

# Install: pip install django-cors-headers

# settings.py
INSTALLED_APPS = [
    ...
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # Harus di atas CommonMiddleware!
    'django.middleware.common.CommonMiddleware',
    ...
]

# Development
CORS_ALLOW_ALL_ORIGINS = True

# Production
CORS_ALLOWED_ORIGINS = [
    "https://aplikasikita.com",
    "https://www.aplikasikita.com",
]

CORS_ALLOW_CREDENTIALS = True

Nginx (Reverse Proxy)

# nginx.conf
server {
    location /api/ {
        # Handle preflight OPTIONS request
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' 'https://aplikasikita.com';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
            add_header 'Access-Control-Max-Age' 86400;
            return 204;
        }

        add_header 'Access-Control-Allow-Origin' 'https://aplikasikita.com' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;

        proxy_pass http://backend:3001;
    }
}

3. Kasus Khusus yang Sering Bikin Bingung

Kasus 1: CORS sudah dikonfigurasi tapi masih error

// Masalah paling umum: credentials: true di frontend tapi
// backend tidak set Access-Control-Allow-Credentials

// Frontend (fetch)
fetch('https://api.aplikasikita.com/users', {
  credentials: 'include',  // Kirim cookies
});

// Backend HARUS set dua hal ini bersamaan:
// 1. Access-Control-Allow-Credentials: true
// 2. Access-Control-Allow-Origin: TIDAK BOLEH pakai wildcard "*"
//    Harus origin spesifik!

// ❌ Ini tidak akan bekerja dengan credentials:
app.use(cors({ origin: '*', credentials: true }));

// ✅ Ini yang benar:
app.use(cors({ origin: 'https://aplikasikita.com', credentials: true }));

Kasus 2: Error hanya di preflight (OPTIONS request)

// Browser mengirim OPTIONS request dulu untuk "custom headers"
// seperti Authorization, Content-Type: application/json, dll.
// Pastikan backend handle OPTIONS method:

app.options('*', cors()); // Enable pre-flight untuk semua routes
app.use(cors(corsOptions));

Kasus 3: Development dengan Vite/CRA

// Solusi terbaik untuk development: gunakan proxy di frontend
// Ini menghindari CORS sama sekali karena request dikirim dari server yang sama

// vite.config.ts
export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3001',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },
});

// Sekarang fetch('/api/users') akan di-proxy ke http://localhost:3001/users
// Tidak ada CORS error karena origin-nya sama

4. Checklist Debug CORS

Cek Cara Verifikasi
Header Access-Control-Allow-Origin ada di response?DevTools → Network → klik request → Response Headers
Origin di header cocok dengan origin frontend?Bandingkan nilai header dengan URL frontend
Jika pakai credentials, origin bukan wildcard *?Cek nilai header, tidak boleh *
OPTIONS preflight berhasil (status 200/204)?DevTools → Network → filter "OPTIONS"
Method yang dipakai ada di Allow-Methods?Cek header Access-Control-Allow-Methods
Custom header ada di Allow-Headers?Cek header Access-Control-Allow-Headers

Kesimpulan

CORS error terlihat menakutkan tapi solusinya selalu ada di satu tempat: konfigurasi header di backend. Ingat tiga aturan utama: (1) set Access-Control-Allow-Origin ke origin yang spesifik, (2) jika pakai credentials jangan pakai wildcard, (3) handle OPTIONS preflight request. Dengan tiga aturan ini, kamu tidak akan pernah bingung dengan CORS lagi.