If you've been developing web apps for a while, there's a 99% chance you've encountered a CORS issue at least once. If you're a beginner, you probably found a one-line fix by Googling the exact error and moved on with your task. Today, with AI tools, you don’t even have to leave your IDE to get a solution.
But did you truly understand what the fix did? Why did the issue occur in the first place? If not, I promise that by the end of this post, you will.
Let’s dive in! 💪
What is CORS?
CORS, or Cross-Origin Resource Sharing, is a browser mechanism that restricts frontend code from making cross-origin requests. It’s not an issue per se but a security feature designed to protect users and websites.
The error you encounter typically occurs when your frontend and backend are deployed on separate domains (or subdomains).
In the example above, frontendcamp.in
makes a request to api.dev.to
. If api.dev.to
doesn’t explicitly allow requests from other origins, the browser will block the request.
Why do browsers do that?
Browsers enforce the SOP or Same-Origin Policy, which dictates how a document or script from one origin can interact with resources on another. This prevents malicious websites from executing code on your site.
Two origins are considered the same if the
protocol
,port
(if specified), andhost
match.
How to fix this issue?
To resolve this, the server must explicitly allow requests from the frontend’s origin.
For example, in the illustration above, api.dev.to
should permit www.frontend.in
to access its resources.
This can done by adding the following response header.
Access-Control-Allow-Origin: https://www.frontendcamp.in
This header informs the browser that www.frontendcamp.in
is authorized to access the resource.
Some developers use
*
as the header value, allowing requests from any origin. Avoid this unless you have a valid reason for doing so.
An alternate solution
You can’t always modify response headers. For instance, when requesting data from an external service, the above solution won’t work.
In such cases, a proxy server can be used.
This works because CORS is enforced only by browsers. With a proxy server in place, the browser perceives the request as originating from the same domain.
Preflight Requests
A preflight request is a CORS request that the browser automatically sends before the actual request when a cross-origin request is not simple.
It uses the OPTIONS
method and includes up to three headers: Access-Control-Request-Method
, Origin
, and optionally, Access-Control-Request-Headers
.
What kind of requests are not considered simple?
A request requires a preflight if it meets any of the following conditions:
- It uses an HTTP method other than
GET
,POST
, orHEAD
. - It includes custom headers, such as
Authorization
orX-Registered-With
. - It sends data in formats other than
application/x-www-form-urlencoded
,multipart/form-data
, ortext/plain
.
For example, if frontendcamp.in
makes a DELETE
request to api.dev.to
, the request flow would be:
- A preflight request is sent.
OPTIONS /v1/posts/224
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: x-requested-with
Origin: https://frontendcamp.in
- The server responds with the applicable CORS policy.
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://frontendcamp.in
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, X-Registered-With
Access-Control-Max-Age: 86400
Access-Control-Allow-Origin
: Allows requests from frontendcamp.in
Access-Control-Allow-Methods
: Specifies allowed HTTP methods
Access-Control-Allow-Headers
: Lists allowed custom headers
Access-Control-Max-Age
: Tells the browser how long to cache the preflight response (in seconds)
- The actual request is made.
Preflight requests can introduce performance overhead. To mitigate this, it's important to set the
Access-Control-Max-Age
header to leverage browser caching.
Common CORS Issues
The knowledge you've gained so far should be enough to debug most CORS-related issues.
Now, let's go through some common scenarios.
Summary
- Cross-Origin Resource Sharing (CORS) is a browser security mechanism that restricts frontend code from making cross-origin requests. It’s not an error but a safeguard.
- Browsers enforce the Same-Origin Policy (SOP) to prevent malicious websites from accessing resources on other domains.
- The server must explicitly allow cross-origin requests by setting the
Access-Control-Allow-Origin
header with the frontend’s origin. - Using * allows any website to access the resource, which can be a security risk. It should only be used when absolutely necessary.
- If you're requesting data from a third-party API and can’t modify its response headers, a proxy server can bypass CORS restrictions.
- When a request is not simple, the browser sends an
OPTIONS
request before the actual request to check if the server allows it. - Requests that use methods other than
GET
,POST
, orHEAD
, include custom headers (e.g.,Authorization
), or send non-standard content types are said to be not "simple". - Frequent preflight requests can cause overhead. Setting the Access-Control-Max-Age header allows the browser to cache the response and improve performance.
Thank you for reading my post. 🙏 I hope you liked it.
Top comments (0)