CORS error adalah salah satu hal pertama yang langsung muncul saat kamu jalanin json-server sebagai mock API lokal. Ini cara fixnya.
Kenapa CORS Muncul di json-server
Browser enforce same-origin policy. Kalau frontend kamu jalan di http://localhost:3000 dan json-server jalan di http://localhost:3001, browser melihat keduanya sebagai origin yang berbeda karena portnya beda. Setiap fetch atau XHR dari frontend ke json-server akan diblok kecuali servernya balas dengan CORS header yang tepat.
Errornya biasanya terlihat seperti ini:
Access to fetch at 'http://localhost:3001/users' from origin 'http://localhost:3000'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present.
Solusinya adalah menjalankan json-server secara programmatic supaya kamu bisa pasang middleware sendiri.
Fix-nya: Custom server.js
Daripada pakai CLI, buat file server.js di root project:
const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router('db.json');
const middlewares = jsonServer.defaults();
server.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', '*');
next();
});
server.use(middlewares);
server.use(router);
server.listen(3001, () => {
console.log('JSON Server is running on port 3001');
});
Jalankan dengan:
node server.js
Middleware-nya jalan sebelum router json-server, jadi setiap response sudah dapat header tersebut. Sampai sini sudah cukup untuk CORS dasar.
Handling Preflight OPTIONS Request
Untuk request yang tidak sederhana - seperti yang punya JSON body, custom header seperti Authorization, atau method PUT, PATCH, DELETE - browser akan kirim preflight request OPTIONS duluan untuk mengecek apakah server mengizinkannya. Tanpa menangani ini, request DELETE atau PATCH kamu tetap akan gagal.
Tambahkan pengecekan OPTIONS di middleware yang sama:
server.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
Ketika browser kirim preflight check tersebut, server kamu langsung balas dengan 200 dan header yang tepat. Request yang sebenarnya pun bisa jalan tanpa masalah.
Wildcard vs Origin Spesifik
Access-Control-Allow-Origin: * aman untuk dev lokal. Ini mengizinkan request dari origin mana saja, yang memang kamu butuhkan saat mock API.
Satu kasus di mana ini tidak berfungsi: kalau kamu perlu kirim cookie atau pakai credentials: 'include' di fetch, browser akan reject wildcard origin. Untuk itu kamu perlu tentukan origin yang spesifik dan set credentials header:
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Credentials', 'true');
Untuk mock server lokal ini hampir tidak pernah dibutuhkan, tapi bagus untuk tahu sebelum kamu debugging 20 menit kenapa credentialed request tidak mau jalan.
Kesimpulan
CORS di json-server bisa di-fix dengan tidak pakai CLI dan buat server.js kecil dengan middleware yang set Access-Control-Allow-Origin dan Access-Control-Allow-Headers. Kalau kamu buat request PUT, PATCH, DELETE, atau request dengan custom header, tambahkan handler OPTIONS juga. Wildcard origin sudah cukup untuk semua kebutuhan dev lokal kecuali kamu perlu credentials.