CORS là cơ chế browser bảo vệ user — server phải opt-in cho phép cross-origin requests.
Preflight mechanism: browser tự động gửi OPTIONS request trước khi gửi request thật nếu là preflighted request (method không phải GET/POST/HEAD, hoặc header không phải simple header như Content-Type: application/json).
Simple requests (GET với simple headers) không cần preflight.
Cấu hình production đúng: cors({ origin: ['https://app.example.com'], methods: ['GET','POST','PUT','PATCH','DELETE'], allowedHeaders: ['Content-Type','Authorization'], credentials: true }) — credentials: true bắt buộc khi gửi cookies/Authorization header.
Quan trọng: khi credentials: true, origin KHÔNG được là * — phải liệt kê explicit.
Debug tips:
- kiểm tra response header
Access-Control-Allow-Origintrong DevTools Network tab, credentials: truenhưng server trả*→ browser chặn,- đặt
cors()TRƯỚC routes để OPTIONS preflight được handle
Pitfall: CORS là browser enforcement — Postman/curl không bị chặn, chỉ browser mới bị.