- What Is CORS?
- CORS stands for Cross-Origin Resource Sharing.
- It is a browser security feature that controls whether one website can make requests to another domain.
- CORS is enforced by browsers to prevent malicious JavaScript from accessing protected resources on other origins.
- A “cross-origin” request happens when:
- Protocol is different:
http:// vs https://
- Domain is different:
api.example.com vs www.example.com
- Port is different:
example.com:8000 vs example.com:8080
- Why Is CORS Needed?
- Without CORS, front-end apps would be unable to call external APIs in modern browsers.
- By default, browsers block JavaScript from reading responses from another origin.
- CORS provides a secure way for servers to say:
- “Yes, this other origin is allowed to read my responses.”
- “Here are the methods, headers, and credentials allowed.”
- How CORS Works (Simplified)
- When the browser sends a cross-origin request, it adds an
Origin header:
Origin: http://localhost:3000
- If the server replies with:
Access-Control-Allow-Origin: http://localhost:3000
- Then the browser allows the response to be read.
- If not, the browser blocks access and shows a CORS error in the console.
- Preflight Requests
- For “complex” requests (e.g.,
PUT, DELETE, or custom headers), the browser sends a preflight request first:
OPTIONS /api/data HTTP/1.1
Origin: http://frontend.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
- The server must respond with:
Access-Control-Allow-Origin: http://frontend.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
- If accepted, the browser continues with the actual request.
- CORS Errors in Practice
- If you see this in the browser:
Access to fetch at 'https://api.example.com' from origin 'http://localhost:3000'
has been blocked by CORS policy
- This means the server did not respond with a valid
Access-Control-Allow-Origin header.
- This is a browser-side rejection — the request is sent, but the response is inaccessible via JS.
- Enabling CORS in Django
- Django does not support CORS natively — you must use the django-cors-headers package.
- Install it via pip:
pip install django-cors-headers
- Add to
INSTALLED_APPS and MIDDLEWARE:
INSTALLED_APPS = [
...
'corsheaders',
...
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...
]
- Allowing Specific Origins
- To allow a single frontend origin (recommended):
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"https://myfrontend.com",
]
- To allow all origins (unsafe for production):
CORS_ALLOW_ALL_ORIGINS = True
- Other options:
CORS_ALLOW_HEADERS — list of allowed headers
CORS_ALLOW_METHODS — allowed HTTP methods
CORS_ALLOW_CREDENTIALS — allow cookies and Authorization headers
- Allowing Cookies (Credentials)
- If your frontend uses
withCredentials or sends cookies, set:
CORS_ALLOW_CREDENTIALS = True
- And your view must respond with:
Access-Control-Allow-Credentials: true
- Note: When credentials are used,
* is not allowed in Access-Control-Allow-Origin.
- Tips for Debugging CORS
- Use browser dev tools → Network tab → check the OPTIONS and actual request
- Check if
Origin is correctly set
- Inspect response headers — especially:
Access-Control-Allow-Origin
Access-Control-Allow-Credentials
Access-Control-Allow-Headers
- Remember: the problem is almost never in the frontend — it’s the server not allowing the origin.
- Security Notes
- Never use
CORS_ALLOW_ALL_ORIGINS=True in production unless you are building a public API with no credentials.
- Always validate
Origin and return only for trusted domains.
- CORS is not a replacement for authentication — it is simply a browser access policy layer.