A Detailed Explanation of CORS (Cross-Origin Resource Sharing) for Frontend Security
1. What is CORS?
CORS (Cross-Origin Resource Sharing) is a W3C standard that allows browsers to send XMLHttpRequest or Fetch requests to servers from different origins, overcoming the restrictions of the Same-Origin Policy. Its core mechanism is negotiating cross-origin permissions through HTTP header fields.
2. Why is CORS Needed?
- Same-Origin Policy Restrictions: Browsers prohibit cross-origin requests by default, but in practice, frontends often need to access APIs from different domains.
- Limitations of Early Solutions: JSONP only supports GET requests and lacks error handling; using a proxy server adds architectural complexity.
- Advantages of CORS: Supports all HTTP methods, with controllable security (configured server-side).
3. Two Types of CORS Requests
-
Simple Request
- Conditions (all must be met):
- Method is one of GET, POST, HEAD;
- Header fields are limited to allowed safe fields (e.g., Accept, Content-Language, Content-Type, etc.);
- Content-Type is
application/x-www-form-urlencoded,multipart/form-data, ortext/plain.
- Process:
- The browser directly sends the cross-origin request, automatically adding
Origin: https://a.comto the request headers; - The server's response headers must include
Access-Control-Allow-Origin: https://a.com(or*to allow any origin); - The browser checks the response headers. If they match, data access is allowed; otherwise, the response is blocked.
- The browser directly sends the cross-origin request, automatically adding
- Conditions (all must be met):
-
Preflight Request
- Trigger Conditions (any one):
- Method is a non-simple method like PUT, DELETE, etc.;
- Contains custom headers (e.g.,
Authorization); - Content-Type is
application/json.
- Process:
- The browser first sends an OPTIONS request (preflight request) with headers including:
Origin: https://a.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: Content-Type,Authorization - The server responds to the preflight request, returning headers such as:
Access-Control-Allow-Origin: https://a.com Access-Control-Allow-Methods: GET,POST,PUT Access-Control-Allow-Headers: Content-Type,Authorization Access-Control-Max-Age: 86400 // Cache duration for preflight results (seconds) - Only after the preflight is successful does the browser send the actual request, following the same process as a simple request thereafter.
- The browser first sends an OPTIONS request (preflight request) with headers including:
- Trigger Conditions (any one):
4. Key HTTP Header Fields Explained
| Field Name | Purpose | Example |
|---|---|---|
Origin |
Declares the origin of the request | Origin: https://a.com |
Access-Control-Allow-Origin |
Origins allowed by the server | * or https://a.com |
Access-Control-Allow-Methods |
Allowed HTTP methods | GET,POST,PUT |
Access-Control-Allow-Headers |
Allowed custom headers | Content-Type,Authorization |
Access-Control-Allow-Credentials |
Whether to allow sending cookies | true (requires frontend to set withCredentials) |
Access-Control-Expose-Headers |
Response headers accessible to the frontend | X-Custom-Header |
5. Requests with Credentials
By default, CORS requests do not send cookies. To include credentials:
- Frontend setup:
fetch(url, { credentials: 'include' // or same-origin }); - The server's response headers must satisfy:
Access-Control-Allow-Origincannot be*; it must specify the exact domain;- Set
Access-Control-Allow-Credentials: true.
6. Common Issues and Solutions
- Preflight Request Fails: Check if the server correctly responds to the OPTIONS request and returns allowed Methods and Headers.
- Response Blocked: Ensure
Access-Control-Allow-Originmatches the Origin, and wildcard*cannot be used when credentials are involved. - Cache Optimization: Use
Access-Control-Max-Ageto reduce the frequency of preflight requests.
7. Practical Configuration Example (Node.js)
// Middleware to set CORS headers
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', 'https://a.com');
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization');
res.setHeader('Access-Control-Allow-Credentials', 'true');
// Directly return 200 for preflight requests
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
8. Summary
CORS enables flexible cross-origin communication securely through a mechanism where the server declares permissions and the browser validates them. During development, pay attention to distinguishing between simple and preflight requests, correctly set header fields, and handle requests with credentials carefully.