$http request blocked due to CORS policy

Loading

What is CORS?

CORS stands for Cross-Origin Resource Sharing. It is a security mechanism implemented by web browsers to prevent malicious websites from accessing resources and data from another domain without permission.

Understanding the Same-Origin Policy

To understand CORS, first you need to understand the Same-Origin Policy (SOP). This policy restricts how documents or scripts loaded from one origin can interact with resources from another origin.

An origin is defined by:

  • Protocol (http or https)
  • Domain (example.com)
  • Port (80, 443, etc.)

Example:

  • Request from http://example.com to http://api.example.com is a cross-origin request, even though the domains look similar.

The Same-Origin Policy prevents this request unless the server at api.example.com explicitly allows it using CORS headers.


Why CORS Exists

The purpose of CORS is to protect users from potential cross-site request forgery (CSRF) and data leakage attacks. For instance, without CORS, any website could make requests to your bank’s API using your browser credentials and steal sensitive information.

By enforcing CORS, browsers ensure that only trusted sources can communicate with external servers, based on server-configured rules.


How the Error Happens

When your front-end JavaScript code tries to send an HTTP request to a different origin (for example, from http://localhost:3000 to https://api.example.com), the browser sends a preflight request (an OPTIONS request) to ask the server: “Is it okay if I make this request?”

If the server does not respond with appropriate CORS headers, the browser blocks the actual request and shows a CORS error in the developer console, like:

Access to XMLHttpRequest at 'https://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Key CORS Headers

To allow CORS, the server needs to include specific headers in its HTTP response:

  1. Access-Control-Allow-Origin: Specifies which origins are allowed (e.g., *, http://localhost:3000).
  2. Access-Control-Allow-Methods: Lists HTTP methods allowed (e.g., GET, POST, PUT).
  3. Access-Control-Allow-Headers: Lists allowed headers (e.g., Content-Type, Authorization).
  4. Access-Control-Allow-Credentials: Whether cookies and credentials are allowed.

Common Use Cases That Trigger CORS

  • JavaScript apps making API calls to a different domain
  • Frontend apps running on localhost trying to communicate with a remote server
  • Mobile or desktop apps using web views
  • Using fetch or axios in a React, Angular, or Vue app to connect to a different server

Step-by-Step: Fixing CORS Error

Step 1: Identify the Error

Check your browser’s console. A typical CORS error message may look like this:

Access to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy

This means the browser blocked the request due to CORS policy violation.


Step 2: Confirm the Server Origin

Ensure you’re calling a server that’s on a different origin. If your frontend is on http://localhost:3000 and your backend is on http://localhost:8000, it’s considered a different origin.


Step 3: Update the Server to Allow CORS

You need to change the server-side code to include the correct CORS headers. This cannot be done from the frontend.

For Node.js with Express:

const cors = require('cors');
app.use(cors());

For more control:

app.use(cors({
origin: 'http://localhost:3000',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true
}));

For Python Flask:

from flask_cors import CORS
CORS(app)

For ASP.NET Core:

services.AddCors(options =>
{
options.AddPolicy("AllowMyOrigin",
builder => builder.WithOrigins("http://localhost:3000")
.AllowAnyMethod()
.AllowAnyHeader());
});
app.UseCors("AllowMyOrigin");

Step 4: Handle Preflight Requests

Browsers send a preflight request (an OPTIONS method call) before the actual request. Your server must handle this.

Example in Express:

app.options('*', cors());

Step 5: Avoid Browser Block in Development

For development purposes, you can use workarounds like:

  • Using a proxy server
    • For React: "proxy": "http://localhost:5000" in package.json
  • Using browser extensions like “CORS Unblock” (not recommended for production)
  • Disabling CORS in browser (very unsafe, never do this for production or real users)

Step 6: Check and Restart

After adding the correct headers on the server, restart your server. Then retry your frontend code.


Advanced CORS Settings

  • Allow specific origins instead of * for better security
  • Enable Access-Control-Allow-Credentials only when necessary
  • Limit allowed methods (GET, POST, etc.)
  • Use HTTPS in production to avoid mixed content issues

Best Practices

  • Always configure CORS on the server, never on the client
  • Never use Access-Control-Allow-Origin: * with credentials
  • Use environment-specific configuration (different CORS settings for dev and prod)
  • Log preflight and actual requests on the server to debug

Important Notes

  • CORS is enforced by browsers, not servers. If you use curl or Postman, you won’t get blocked by CORS.
  • If you’re getting blocked, it’s not because of a problem in your code, but because the server is not configured to allow your request.
  • CORS errors don’t reach your JavaScript .catch() block; they are blocked before your code gets the response.

Leave a Reply

Your email address will not be published. Required fields are marked *