In the previous article, we learned that browsers sometimes send an OPTIONS request before the actual Cross-Origin request. This process is known as a CORS Preflight Request.
But does this happen for every request?
The answer is no.
Browsers only perform a Preflight Request when the request does not qualify as a Simple Request.
What Is a Simple Request?
A Simple Request is a Cross-Origin request that satisfies a specific set of conditions defined by the Fetch specification.
Since these requests are considered low risk, the browser sends them directly without performing a Preflight check.
CORS rules still apply to the response, but no preliminary OPTIONS request is needed.
Requirements for a Simple Request
A request is considered simple only if all of the following conditions are met.
1. HTTP Method
The request method must be one of:
GETHEADPOST
Methods such as PUT, PATCH, and DELETE automatically trigger a Preflight Request.
2. Request Headers
The request may only include CORS-safelisted request headers, such as:
AcceptAccept-LanguageContent-Language
Adding headers like:
Authorization: Bearer <token>
or
X-API-Key: 123456
causes the browser to perform a Preflight Request.
3. Content-Type
If the request has a body, its Content-Type must be one of:
application/x-www-form-urlencodedmultipart/form-datatext/plain
Using a content type such as:
application/json
makes the request non-simple and triggers a Preflight Request.
This is one of the most common reasons developers see OPTIONS requests in modern web applications.
Examples
This request is simple:
fetch("/users")
No Preflight Request is sent.
This request is also simple:
fetch("/login", {
method: "POST",
headers: {
"Content-Type": "text/plain"
}
})
Again, no Preflight is required.
However, this request is not simple:
fetch("/login", {
method: "POST",
headers: {
"Content-Type": "application/json"
}
})
The browser first sends an OPTIONS request.
The same happens here:
fetch("/profile", {
headers: {
"Authorization": "Bearer token"
}
})
Because the Authorization header is not CORS-safelisted, a Preflight Request is required.
Summary
A browser sends a Preflight Request only when a Cross-Origin request does not meet the requirements of a Simple Request.
The most common triggers are:
- Using methods such as
PUT,PATCH, orDELETE - Including non-safelisted headers such as
Authorization - Using content types like
application/json
This is why seeing an OPTIONS request before the actual request is completely normal in many modern APIs.
Top comments (0)