Cara Memperbaiki Error CORS
“Blocked by CORS policy” adalah cara browser melindungi pengguna, bukan bug di kodemu. Perbaikannya selalu ada di server yang menerima request. Panduan ini menjelaskan apa yang diperiksa browser dan memberi konfigurasi yang berfungsi untuk kasus umum.
Apa itu CORS sebenarnya
Browser memblokir JavaScript di https://app.example.com agar tidak bisa membaca respons dari origin lain (skema + host + port), misalnya https://api.example.com, kecuali server tersebut mengizinkannya. Server memberi izin lewat header respons Access-Control-Allow-*. Request dari curl, Postman, atau backend kamu tidak terpengaruh. Itulah sebabnya “jalan di Postman” tetapi gagal di browser.
Baca pesan errornya
- “No ‘Access-Control-Allow-Origin’ header is present” — server sama sekali tidak mengirim header CORS, atau halaman error (404, 500) dikembalikan tanpa header tersebut.
- “Response to preflight request doesn’t pass access control check” — request
OPTIONSgagal: tidak ditangani, mengembalikan error, atau tidak punya header yang dibutuhkan. - “The value of the ‘Access-Control-Allow-Origin’ header must not be the wildcard ‘*’ when credentials mode is ‘include’” — kamu mengirim cookie, jadi server harus memantulkan origin yang tepat.
Periksa request yang gagal di DevTools → Network, atau cek header respons yang sebenarnya dengan HTTP Header Checker.
Request sederhana dan preflight
Sebuah request disebut “sederhana” jika berupa GET, HEAD, atau POST dengan header dasar saja dan body berupa form atau teks biasa. Selain itu, seperti Content-Type: application/json, header Authorization, PUT, atau DELETE, akan membuat browser mengirim request OPTIONS preflight terlebih dahulu. Server kamu harus merespons dengan status 204 atau 200 dan header berikut:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 600
Contoh konfigurasi yang berfungsi
Express dengan paket cors:
const cors = require('cors');
app.use(cors({
origin: ['https://app.example.com'],
credentials: true, // hanya jika kamu mengirim cookie
methods: ['GET', 'POST', 'PUT', 'DELETE'],
}));
Nginx:
location /api/ {
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin "https://app.example.com" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
add_header Access-Control-Max-Age 600;
return 204;
}
add_header Access-Control-Allow-Origin "https://app.example.com" always;
proxy_pass http://backend;
}
Flag always itu penting: tanpanya Nginx menghapus header pada respons error, dan browser lalu melaporkan error CORS alih-alih error 500 yang sebenarnya. Untuk server lain (Vercel, Netlify, Cloudflare Workers, Apache), buat header dengan CORS Header Generator.
Cookie dan kredensial
Agar cookie terkirim lintas origin, request perlu credentials: 'include' (fetch) dan server harus merespons dengan Access-Control-Allow-Credentials: true serta origin yang tepat. Jangan pernah pakai *. Cookie itu sendiri perlu SameSite=None; Secure. Saat kamu memantulkan origin dari daftar, kirim juga Vary: Origin agar cache tidak menyajikan header satu situs ke situs lain.
Yang sebaiknya tidak dilakukan
- Jangan memantulkan header
Originapa pun saat kredensial diaktifkan. Itu membuat setiap situs web bisa membaca data pengguna kamu. - Jangan “memperbaiki” CORS dengan ekstensi browser atau proxy publik. Itu hanya menyembunyikan masalah di mesin kamu.
- Jika API itu milik kamu dan berada di situs yang sama, reverse proxy (same origin) menghilangkan CORS sepenuhnya.
Ulangi request browser dengan API Tester, atau ubah menjadi kode dengan cURL to Code.