Halo, teman-teman! Pernahkah kamu sedang asyik-asyiknya ngoding frontend, mencoba melakukan fetch data dari API atau backend yang sudah kamu buat susah payah, tapi malah disambut dengan tulisan merah menyala di console browser seperti ini:
“Access to fetch at ‘https://api.domain.com‘ from origin ‘https://domain.com‘ has been blocked by CORS policy…”
Rasanya pasti bikin frustrasi, bukan? Apalagi kalau deadline sudah di depan mata. Masalah CORS (Cross-Origin Resource Sharing) ini memang sering jadi momok.
Di artikel kali ini, kita akan bongkar tuntas kenapa error ini bisa muncul, khususnya pada kasus penggunaan subdomain, dan bagaimana cara paling ampuh untuk menyelesaikannya. Mari kita bahas!
Apa Itu CORS dan Kenapa Browser Memblokirnya?
Secara sederhana, CORS adalah mekanisme keamanan standar pada browser modern (Chrome, Firefox, Safari, dll). Browser memiliki aturan baku yang disebut Same-Origin Policy (SOP). Aturan ini melarang sebuah website mengambil data dari alamat (URL) yang berbeda secara diam-diam.
Kenapa? Bayangkan jika tidak ada CORS. Sebuah website jahat yang kamu kunjungi bisa diam-diam mengirimkan request ke https://klikbca.com atau aplikasi perbankanmu untuk mencuri data session saat kamu sedang login. Mengerikan, kan? Karena itulah browser bertindak sebagai “satpam” yang mencegat request lintas alamat ini.
“Loh, Frontend dan API Saya Masih Satu Domain, Kok Kena CORS?”
Ini adalah jebakan betmen yang paling sering memakan korban. Banyak developer menggunakan struktur seperti ini:
- Frontend:
https://toko-baju.com - API/Backend:
https://api.toko-baju.com
Secara bisnis, itu memang satu kesatuan. Tapi di mata browser, keduanya adalah alamat yang berbeda (Cross-Origin).
Sebuah request hanya dianggap Same-Origin (Satu Origin) apabila ketiga hal ini sama persis:
- Protokol: (Sama-sama
httpatauhttps) - Host/Domain: (Harus sama persis karakternya. Subdomain dihitung berbeda!)
- Port: (Sama-sama jalan di port
80,443, atau port kustom lainnya)
Karena host pada toko-baju.com berbeda teks dengan api.toko-baju.com, maka aturan CORS otomatis menyala.
Konfigurasi Header di Sisi Backend
Kunci utama untuk menyelesaikan masalah CORS selalu ada di sisi Backend/Server. Kamu tidak bisa (dan tidak boleh) mengakali CORS dari sisi frontend (React, Vue, HTML biasa) demi alasan keamanan.
Kamu harus menginstruksikan backend agar memberikan izin (lewat HTTP Headers) kepada browser bahwa frontend milikmu aman untuk mengakses data. Berikut adalah cara konfigurasinya di beberapa environment populer:
1. Konfigurasi di PHP Native
Jika API-mu dibangun menggunakan PHP murni, tambahkan baris kode ini di bagian paling atas file PHP kamu (biasanya di index.php atau file router utama):
(Tips: Gunakan * pada Allow-Origin jika API-mu bersifat publik dan boleh diakses siapa saja, tapi hindari ini untuk data sensitif).
2. Konfigurasi di Node.js (Express)
Untuk kamu yang menggunakan Express.js, cara paling gampang adalah menggunakan library resmi cors.
Pertama, install library-nya:
npm install cors
Lalu panggil di file utamamu (app.js atau server.js):
const express = require('express'); const cors = require('cors'); const app = express(); // Konfigurasi CORS const corsOptions = { origin: 'https://toko-baju.com', // Domain frontend-mu methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization'] }; // Gunakan middleware CORS app.use(cors(corsOptions)); app.get('/api/data', (req, res) => { res.json({ message: "Berhasil mengambil data tanpa error CORS!" }); }); app.listen(3000, () => console.log('Server berjalan...'));
3. Konfigurasi di Laravel
Jika kamu menggunakan framework Laravel (versi 7 ke atas), konfigurasi CORS sudah disediakan secara bawaan. Kamu hanya perlu mengedit file config/cors.php.
// config/cors.php return [ 'paths' => ['api/*', 'sanctum/csrf-cookie'], 'allowed_methods' => ['*'], // Izinkan semua metode (GET, POST, OPTIONS, dll) 'allowed_origins' => ['https://toko-baju.com'], 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], // Izinkan semua header 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => false, ];
Jangan lupa jalankan perintah php artisan optimize:clear atau php artisan config:clear setelah mengubah file konfigurasi.
Penanganan dari Sisi Pengaturan Server
Terkadang, aplikasi backend tidak bisa diutak-atik lagi karena satu dan lain hal. Jika situasinya begini, penyelesaian bisa dilakukan dari level Web Server langsung. Idenya adalah mencegat request OPTIONS di pintu depan (server) sebelum sempat masuk ke kodingan aplikasi.
1. Apache
Jika Menggunakan Apache (via file .htaccess): Letakkan kode ini di dalam file .htaccess pada folder root API-mu:
Header always set Access-Control-Allow-Origin "https://toko-baju.com" Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT" Header always set Access-Control-Allow-Headers "Content-Type, Authorization, Accept, Origin" RewriteEngine On RewriteCond %{REQUEST_METHOD} OPTIONS RewriteRule ^(.*)$ $1 [R=200,L]
2. Nginx
Jika Menggunakan NGINX: Tambahkan konfigurasi ini di dalam Server Block (Virtual Host) NGINX pada bagian location /:
location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' 'https://toko-baju.com' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always; add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, Origin' always; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; return 204; } add_header 'Access-Control-Allow-Origin' 'https://toko-baju.com' always; # ... (Konfigurasi proxy_pass atau fastcgi_pass aplikasimu) ... }
Kesimpulan
CORS Error sebenarnya bukanlah sebuah “error” atau bug dari aplikasimu, melainkan bentuk perlindungan browser yang bekerja sebagaimana mestinya. Masalah CORS (terutama pada kasus subdomain) hanya bisa diselesaikan dengan memberikan Header Izin (Access-Control-Allow-Origin) dari sisi server atau API. Semoga artikel ini bisa membantumu menghilangkan teks merah menyebalkan di console browser. Selamat ngoding dan semoga tidak pusing lagi gara-gara CORS!