Updated April 2026
Preflight Request
A preflight request is an automatic HTTP OPTIONS request browsers send before cross-origin requests that use non-simple methods (PUT, DELETE, PATCH) or custom headers (like Authorization or Content-Type: application/json). The server must return valid CORS headers or the actual request is blocked.
When browsers send a preflight
A preflight is sent when the cross-origin request uses:
- Methods other than GET, POST, or HEAD
- POST with Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain
- Any custom headers (Authorization, X-Custom-Header, etc.)
Simple GET requests, and POST with form encoding, go directly without a preflight.
What the preflight looks like
OPTIONS /api/data HTTP/1.1 Host: api.example.com Origin: https://app.example.com Access-Control-Request-Method: POST Access-Control-Request-Headers: Content-Type, Authorization
What the server must return
HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://app.example.com Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Content-Type, Authorization Access-Control-Max-Age: 86400
If any of these are missing or wrong, the browser blocks the actual request and shows a CORS error.
Nginx — handle OPTIONS
if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin "https://app.example.com"; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"; add_header Access-Control-Allow-Headers "Content-Type, Authorization"; add_header Access-Control-Max-Age 86400; return 204;
}
Caching the preflight
Access-Control-Max-Age: 86400 tells the browser to cache the preflight result for 24 hours. Without it, the browser sends an OPTIONS request before every single cross-origin request.