CORS: Simple vs Non-Simple Requests
Which requests trigger a preflight and which do not.
CORS: Simple vs Non-Simple Requests
Simple Requests (No Preflight)
- Methods: GET, POST, HEAD.
- Content-Type: application/x-www-form-urlencoded, multipart/form-data, text/plain.
- Headers: only CORS-safe headers (Accept, Accept-Language, Content-Language, Content-Type).
- No custom headers (no Authorization, no X-Custom-Header).
The browser sends the request directly and checks the response headers.
Non-Simple Requests (Preflight Required)
- Methods: PUT, DELETE, PATCH, CONNECT, TRACE.
- Content-Type: application/json, text/xml, etc.
- Custom headers: Authorization, X-Requested-With, X-Custom-Header.
- ReadableStream in the request body.
The browser sends an OPTIONS preflight first.
Example: Simple
fetch("https://api.example.com/data"); // GET, no custom headers -> simple
Example: Non-Simple
fetch("https://api.example.com/users", { method: "PUT", headers: { "Content-Type": "application/json", "Authorization": "Bearer token" }, body: JSON.stringify({ name: "Kunal" }), }); // PUT + JSON + Authorization -> preflight
The Takeaway
Simple: GET/POST/HEAD with safe content types and no custom headers (no preflight). Non-simple: PUT/DELETE/PATCH, JSON content type, or custom headers (preflight required). Most modern API calls (JSON + Authorization) are non-simple and trigger a preflight.
GET, POST, or HEAD with a safe Content-Type (form-urlencoded, multipart, text/plain) and no custom headers. The browser sends it directly without a preflight and checks the response headers.
PUT, DELETE, PATCH, or any request with application/json Content-Type or custom headers (Authorization, X-Custom). These trigger a preflight OPTIONS request before the actual request.
Yes. application/json is not a 'safe' Content-Type. The browser sends an OPTIONS preflight first. Only form-urlencoded, multipart/form-data, and text/plain are safe.
Yes. Authorization is a custom header (not in the CORS-safe list). Any request with an Authorization header triggers a preflight, even a GET.
Use only GET/POST/HEAD with safe Content-Types and no custom headers. In practice, this is rarely possible for modern APIs (JSON + Authorization). Instead, configure the server to handle preflight correctly with Access-Control-Max-Age to cache the result.
Ready to master React completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master React
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

