For "non-simple" requests (POST with JSON, custom headers) the browser first sends a preflight request using the OPTIONS method. The server returns headers allowing or blocking the request. If allowed — the browser sends the actual request.
Access-Control-Allow-Origin — domain(s) permitted access (* or a specific domain)Access-Control-Allow-Methods — allowed HTTP methodsAccess-Control-Allow-Headers — allowed request headersAccess-Control-Allow-Credentials — whether cookies may be sent with the requestCORS headers are set by the server — through middleware, Nginx/Apache configuration, or directly in code. A "blocked by CORS policy" error is always resolved on the server side, not the client.