
Types of CORS API Calls
Types of CORS (Cross-Origin Resource Sharing)
CORS (Cross-Origin Resource Sharing) defines how web browsers handle cross-origin requests, allowing or restricting access based on policies set by the server. There are three types of CORS requests:
Simple Requests
These are basic requests that do not trigger a preflight (OPTIONS request). They are automatically sent by the browser without an extra preflight check.
Requirements for a Simple Request:
- Must use GET, POST, or HEAD methods.
- Allowed headers:
Accept
Accept-Language
Content-Language
Content-Type
(Onlyapplication/x-www-form-urlencoded
,multipart/form-data
, ortext/plain
).
- Must not use custom headers like
Authorization
,X-API-Key
, etc. - Cannot include
cookies
orcredentials
.
Example: Fetching Data (Simple CORS Request)
fetch("https://api.example.com/data")
.then(response => response.json())
.then(data => console.log(data));
No Preflight Needed! The browser directly sends the request.
Preflight Requests
If a request does not qualify as a simple request, the browser sends a preflight OPTIONS request to check if the server allows it.
When is a Preflight Request Triggered?
- Uses HTTP methods other than
GET
,POST
, orHEAD
(e.g.,PUT
,DELETE
,PATCH
). - Uses custom headers (e.g.,
Authorization
,X-API-Key
). - Includes credentials (
withCredentials: true
). Content-Type
is not one of the allowed types (application/json
,text/plain
, etc.).
Example: Preflight Request Flow
1️. Browser Sends Preflight (OPTIONS Request)
OPTIONS /update HTTP/1.1
Origin: https://myfrontend.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Authorization
2️. Server Responds with Allowed Policies
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://myfrontend.com
Access-Control-Allow-Methods: PUT, DELETE
Access-Control-Allow-Headers: Authorization
3️. Browser Sends Actual Request (if allowed)
fetch("https://api.example.com/update", {
method: "PUT",
headers: {
"Authorization": "Bearer token"
}
})
.then(response => response.json())
.then(data => console.log(data));
Server must explicitly allow the request method and headers.
Credentialed Requests (With Cookies/Auth Headers)
By default, browsers do not send credentials (cookies, authentication headers, etc.) with CORS requests.
To send cookies or authentication headers, both client and server must allow it:
- Client:
credentials: "include"
- Server:
Access-Control-Allow-Credentials: true
Example: Credentialed CORS Request
fetch("https://api.example.com/user", {
credentials: "include"
})
.then(response => response.json())
.then(data => console.log(data));
Server Response (MUST Allow Credentials)
Access-Control-Allow-Origin: https://myfrontend.com
Access-Control-Allow-Credentials: true
Important: Access-Control-Allow-Origin
cannot be *
when credentials: true
.
Comparison Table
Type | Triggers Preflight? | Allows Custom Headers? | Allows Credentials? |
---|---|---|---|
Simple Request | ❌ No | ❌ No | ❌ No |
Preflight Request | ✅ Yes | ✅ Yes | ✅ Yes (if allowed) |
Credentialed Request | ✅ Yes (if needed) | ✅ Yes | ✅ Yes |
Conclusion
- Simple Requests are limited to basic use cases (GET, POST, HEAD).
- Preflight Requests are needed for security-sensitive operations.
- Credentialed Requests require explicit
credentials: "include"
and cannot use*
as the allowed origin.
Understanding these types helps developers configure CORS properly and avoid issues!