AJAX - Cross-Origin Resource Sharing (CORS) in Depth for AJAX
Cross-Origin Resource Sharing (CORS) is a security mechanism implemented by browsers to control how web applications running on one origin can request resources from another origin. An “origin” is defined by the combination of protocol, domain, and port. For example, http://example.com and https://example.com are considered different origins, as are http://example.com:3000 and http://example.com:5000.
1. Why CORS Exists
Browsers enforce a policy called the Same-Origin Policy (SOP), which restricts AJAX requests from one origin to another by default. This is done to prevent malicious websites from accessing sensitive data from another site where a user may already be authenticated.
CORS relaxes this restriction in a controlled way. It allows servers to explicitly specify which external origins are permitted to access their resources.
2. How CORS Works
CORS is enforced by the browser, not the server. The server only sends headers indicating what is allowed, and the browser decides whether to allow or block the request.
When an AJAX request is made to a different origin, the browser includes an Origin header in the request. The server then responds with specific CORS headers to indicate whether the request is permitted.
Example:
Request Header:
Origin: https://client-app.com
Response Header:
Access-Control-Allow-Origin: https://client-app.com
If the origin matches, the browser allows the response to be accessed. Otherwise, it blocks it.
3. Simple Requests vs Preflight Requests
CORS distinguishes between two types of requests:
a) Simple Requests
These are requests that meet certain conditions:
-
Use methods like GET, POST, or HEAD
-
Use only standard headers (like Accept, Content-Type with limited values)
For simple requests, the browser sends the request directly and checks the response headers afterward.
b) Preflight Requests
For more complex operations, the browser sends a preliminary request called a “preflight” request using the OPTIONS method. This checks whether the actual request is safe to send.
Preflight request includes:
OPTIONS /api/data
Origin: https://client-app.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
Server response:
Access-Control-Allow-Origin: https://client-app.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
Only if the server अनुमति matches the request will the browser proceed with the actual AJAX call.
4. Important CORS Headers
-
Access-Control-Allow-Origin
Specifies which origin is allowed. Can be a specific domain or*(all domains). -
Access-Control-Allow-Methods
Lists HTTP methods allowed (GET, POST, PUT, DELETE, etc.). -
Access-Control-Allow-Headers
Specifies which custom headers can be used in the request. -
Access-Control-Allow-Credentials
Indicates whether cookies or authentication data can be included. -
Access-Control-Expose-Headers
Lists headers that the browser is allowed to access from the response. -
Access-Control-Max-Age
Defines how long the preflight response can be cached.
5. Credentials and CORS
By default, browsers do not send cookies or authentication headers in cross-origin requests. To include credentials:
Client-side:
fetch(url, {
credentials: 'include'
});
Server-side must include:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://client-app.com
Note that * cannot be used with credentials; a specific origin must be defined.
6. Common CORS Issues in AJAX
-
Missing
Access-Control-Allow-Originheader -
Incorrect handling of preflight requests
-
Using
*with credentials (not allowed) -
Server not supporting OPTIONS method
-
Mismatched headers between request and allowed headers
These issues result in the browser blocking the response, even if the server processed the request successfully.
7. Security Considerations
CORS is not a security feature for the server; it is a browser-enforced policy. Servers must still implement proper authentication and authorization.
Important practices:
-
Avoid using
Access-Control-Allow-Origin: *for sensitive APIs -
Restrict allowed origins to trusted domains
-
Validate incoming requests on the server side
-
Use tokens (JWT, OAuth) instead of relying solely on cookies
8. Debugging CORS Problems
CORS errors appear in the browser console, not as standard HTTP errors. Developers should:
-
Inspect request and response headers in Developer Tools
-
Check if preflight requests are being sent and handled correctly
-
Verify that server headers match client request expectations
9. Real-World Usage in AJAX
In modern web applications, front-end and back-end are often hosted on different domains (for example, a React frontend and a REST API backend). CORS becomes essential to enable communication between them.
Without proper CORS configuration, AJAX calls using fetch or XMLHttpRequest will fail due to browser restrictions, even if the API is functioning correctly.
10. Summary
CORS is a critical concept for enabling secure cross-origin AJAX communication. It works through HTTP headers that define access rules, supports both simple and preflighted requests, and must be carefully configured to balance accessibility and security. Understanding how browsers enforce CORS and how servers respond to it is essential for building modern web applications that interact across domains.