CORS (Cross-Origin Resource Sharing) là cơ chế browser ngăn JavaScript đọc response từ origin khác (khác domain/port/protocol) — Same-Origin Policy. Khi cần cross-origin, server phải trả về CORS headers. Simple requests (GET/POST với Content-Type text/plain hoặc form) không cần preflight. Preflight request là OPTIONS request tự động browser gửi trước khi gửi non-simple request (PUT/DELETE/custom headers/JSON body) — server phải trả Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Origin.
Cấu hình đúng: Access-Control-Allow-Origin: https://yourdomain.com (không nên cho authenticated endpoints), Access-Control-Allow-Credentials: true nếu dùng cookies, Access-Control-Max-Age: 86400 để cache preflight. Lỗi phổ biến: đặt cùng credentials: true sẽ bị browser block; CORS chỉ là browser policy, không bảo vệ server-to-server calls.
CORS (Cross-Origin Resource Sharing) is a browser mechanism that prevents JavaScript from reading responses from a different origin (different domain, port, or protocol) — the Same-Origin Policy. When cross-origin access is needed, the server must return CORS headers. Simple requests (GET/POST with Content-Type of text/plain or a form type) do not require a preflight. A preflight request is an OPTIONS request automatically sent by the browser before non-simple requests (PUT/DELETE/custom headers/JSON body) — the server must respond with Access-Control-Allow-Methods, Access-Control-Allow-Headers, and Access-Control-Allow-Origin.
Correct configuration: Access-Control-Allow-Origin: https://yourdomain.com (avoid for authenticated endpoints), Access-Control-Allow-Credentials: true if cookies are used, Access-Control-Max-Age: 86400 to cache the preflight result. Common mistake: using together with credentials: true will be blocked by the browser; CORS is a browser-only policy and does not protect server-to-server calls.