Real-world examples of handling CORS errors in front-end applications

If you build anything in the browser that talks to an API, you’ve hit CORS errors. They’re noisy, confusing, and they always show up five minutes before a deadline. The good news: once you’ve seen a few real examples of handling CORS errors in front-end applications, the patterns become predictable. You stop guessing and start diagnosing. In this guide, we’ll walk through practical examples of examples of handling CORS errors in front-end applications: React apps calling Node and Python backends, static SPAs hitting third-party APIs, and modern setups using proxies and API gateways. Instead of hand-wavy theory, we’ll focus on network requests, browser behavior, and concrete response headers. You’ll see how to recognize preflight failures, misconfigured `Access-Control-Allow-Origin` headers, credential issues, and more—and how to fix them without just slapping `*` on everything and hoping for the best. If you want realistic, copy-paste-able patterns you can adapt to your own stack, you’re in the right place.
Written by
Jamie
Published

Let’s start with concrete examples of handling CORS errors in front-end applications, because that’s what actually helps when production is on fire.

Picture this: your React app at https://app.example.com calls an API at https://api.example.com. Locally it worked fine, but in production the browser console screams:

Access to fetch at 'https://api.example.com/users' from origin 'https://app.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

On the front-end, you see a generic TypeError: Failed to fetch. The request never reaches your app code, so you can’t just try/catch and move on. You need a mix of front-end awareness and server-side configuration.

Below are several real examples of handling CORS errors in front-end applications, with specific patterns you can reuse.


Example of a simple CORS error in a React SPA and how to tame it

This is one of the best examples because it hits almost everyone building SPAs.

You have a React app created with Vite or Create React App, running on http://localhost:5173, calling a Node/Express API running on http://localhost:4000:

// React front-end
fetch('http://localhost:4000/api/profile', {
  method: 'GET',
})
  .then(res => res.json())
  .then(data => setProfile(data));

The browser logs:

Access to fetch at 'http://localhost:4000/api/profile' from origin 'http://localhost:5173' has been blocked by CORS policy.

How the front-end should respond

You can’t fix this purely from the front-end, but you can:

  • Confirm it’s a CORS issue using the Network tab: you’ll see the request, but the response will be blocked.
  • Avoid hiding the error: log a clear message when response.type === 'opaque' or when !response.ok.
fetch('http://localhost:4000/api/profile')
  .then(response => {
    if (response.type === 'opaque') {
      console.error('Likely CORS issue: opaque response. Check server headers.');
    }
    if (!response.ok) {
      console.error('HTTP error', response.status);
    }
    return response.json();
  })
  .then(setProfile)
  .catch(err => {
    console.error('Network or CORS error', err);
  });

Server-side fix that pairs with the front-end

On the Express server:

import express from 'express';
import cors from 'cors';

const app = express();

app.use(cors({
  origin: 'http://localhost:5173',
}));

app.get('/api/profile', (req, res) => {
  res.json({ name: 'Jamie', role: 'Engineer' });
});

app.listen(4000);

This is one of the cleanest examples of examples of handling CORS errors in front-end applications: diagnose in the browser, configure on the server, and keep front-end logging honest so the next developer isn’t guessing.


Handling preflight failures: a real example of OPTIONS going wrong

Modern browsers send a preflight OPTIONS request when your request is not a “simple” one (for example, custom headers or non-GET/POST methods, or JSON with a non-default Content-Type).

Imagine a Vue app calling a Python FastAPI backend:

// Vue front-end
await fetch('https://api.example.com/admin/users', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
    'X-Admin-Token': adminToken,
  },
  body: JSON.stringify({ disabled: true }),
});

The browser silently sends an OPTIONS request first. If the server doesn’t respond correctly, you’ll see:

Response to preflight request doesn't pass access control check: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

Front-end behavior that helps debugging

In this situation, the front-end can:

  • Temporarily remove custom headers and switch to GET or POST with simpler headers to confirm it’s a preflight issue.
  • Log clear metadata about the failing call:
try {
  const res = await fetch(url, options);
  if (!res.ok) {
    console.error('API error', { url, status: res.status });
  }
} catch (error) {
  console.error('Likely CORS or network failure', { url, method: options.method, error });
}

This is another one of those real examples of handling CORS errors in front-end applications where the main fix is server-side, but the front-end can speed up diagnosis.

Backend configuration to support preflight

For FastAPI:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

origins = [
    "https://app.example.com",
]

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

Now the OPTIONS preflight returns headers like:

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: X-Admin-Token, Content-Type

Using a development proxy: one of the best examples for front-end teams

Front-end developers often don’t control the API. In that case, a dev proxy is one of the best examples of handling CORS errors in front-end applications without constantly bothering backend teams.

Example: React dev server proxy

With Vite, add this to vite.config.ts:

export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'https://api.example.com',
        changeOrigin: true,
        secure: true,
      },
    },
  },
});

Then in your React code:

fetch('/api/users'); // no CORS, because browser origin is same as dev server

In production you still need proper CORS headers from the API, but for local development this pattern removes a huge amount of noise and gives you clean examples of how the front-end can sidestep CORS during iteration.


Handling CORS with credentials: cookies, sessions, and gotchas

Another very common example of handling CORS errors in front-end applications is when you start sending cookies.

Imagine a Next.js app at https://app.example.com calling https://auth.example.com with session cookies.

Front-end code:

const res = await fetch('https://auth.example.com/me', {
  credentials: 'include',
});

If the server responds with:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

the browser rejects it. You’ll see:

The value of the 'Access-Control-Allow-Origin' header in the response must not be '*'
when the request's credentials mode is 'include'.

Front-end adjustments

From the front-end side, you:

  • Confirm that credentials: 'include' is actually needed (sometimes you can use tokens in headers instead).
  • Make sure you’re not accidentally mixing same-site cookie settings that prevent cookies from being sent at all.

Example of logging cookie-related behavior:

fetch('https://auth.example.com/me', {
  credentials: 'include',
})
  .then(r => {
    if (!r.ok) {
      console.error('Auth error, status:', r.status);
    }
    return r.json();
  })
  .catch(err => {
    console.error('Network/CORS issue with auth endpoint', err);
  });

Server expectations

On the server, you need specific origins when using credentials:

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true

This is one of the cleaner examples of examples of handling CORS errors in front-end applications that involve authentication: the front-end sets credentials, the server sets a non-wildcard origin and the credentials flag, and both sides agree on cookie behavior.

For updated browser behavior on cookies and cross-site requests, the MDN documentation is still the best reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS


Public third-party APIs: when you can’t touch the server

Sometimes you’re hitting public APIs (maps, weather, analytics) and you have no control over CORS headers. A practical example of handling CORS errors in front-end applications here is to stop calling those APIs directly from the browser.

Example: weather API from a static site

You have a static site on https://myblog.com trying to call a third-party weather API:

fetch('https://api.weather.example.com/current?city=Boston');

The API doesn’t send Access-Control-Allow-Origin for your domain, and you get blocked.

Realistic options

In 2024–2025, the two most common patterns are:

  • Use your own edge function or serverless function (Netlify Functions, Vercel Functions, AWS Lambda) as a proxy.
  • Or, if the provider offers it, use a CORS-friendly SDK that talks to their backend instead of direct browser calls.

Proxy example (Node-based serverless function):

export default async function handler(req, res) {
  const { city } = req.query;
  const upstream = await fetch(
    `https://api.weather.example.com/current?city=${encodeURIComponent(city)}`,
    {
      headers: { 'X-API-Key': process.env.WEATHER_API_KEY },
    }
  );

  const data = await upstream.json();

  res.setHeader('Access-Control-Allow-Origin', 'https://myblog.com');
  res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

  res.status(upstream.status).json(data);
}

From the front-end’s perspective, you now call your own domain, and CORS works because you control the headers.


API gateways and microservices: modern 2024–2025 patterns

As teams move to microservices and API gateways (Kong, NGINX, AWS API Gateway, Cloudflare API Gateway), CORS policies are often centralized.

One of the more modern examples of handling CORS errors in front-end applications is when:

  • The front-end calls https://api.example.com.
  • That hits an API gateway.
  • The gateway routes to multiple internal services.

If CORS is misconfigured at the gateway, every front-end request fails.

Example: AWS API Gateway with a React front-end

React app at https://dashboard.example.com calling an API Gateway endpoint:

const res = await fetch('https://api.example.com/v1/reports');

You see:

CORS header 'Access-Control-Allow-Origin' missing

In this case, the fix is usually at the gateway level:

  • Enable CORS on the resource and method in API Gateway.
  • Ensure both the preflight OPTIONS and the actual method (GET/POST/etc.) return the same CORS headers.

The front-end’s role is mostly diagnostic:

  • Capture failing URLs and methods.
  • Distinguish between HTTP errors (like 401, 500) and CORS/network errors.

With modern observability tools (OpenTelemetry, distributed tracing), teams are increasingly wiring front-end error reporting into backend traces. The pattern: when a CORS error shows up in the browser, it’s tied to a specific gateway config or service deployment, making these examples of handling CORS errors in front-end applications much easier to track.

For general security guidance on cross-origin requests and browser behavior, the OWASP guidance on CORS remains useful reading: https://owasp.org/www-community/attacks/CORS_Misconfiguration


SPA frameworks and CORS: Angular, Next.js, and beyond

Different frameworks have slightly different ergonomics, but the CORS story is the same.

Angular example: using proxies in development

Angular’s CLI has a built-in proxy mechanism. A very practical example of handling CORS errors in front-end applications built with Angular is to configure proxy.conf.json:

{
  "/api": {
    "target": "https://api.example.com",
    "secure": true,
    "changeOrigin": true,
    "logLevel": "debug"
  }
}

Then in angular.json you wire the proxy into the dev server. Your Angular app calls /api/... without CORS issues during local development.

Next.js example: API routes as a CORS-friendly facade

Next.js lets you create API routes that live alongside your pages. A realistic example of handling CORS errors in front-end applications built with Next.js is to use these routes as a CORS-friendly backend.

/pages/api/users.ts:

import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const upstream = await fetch('https://external-api.example.com/users');
  const data = await upstream.json();

  res.setHeader('Access-Control-Allow-Origin', 'https://my-next-app.com');
  res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');

  res.status(200).json(data);
}

Your front-end now calls /api/users on the same origin, avoiding CORS entirely.

These are some of the best examples of examples of handling CORS errors in front-end applications in modern frameworks: hide cross-origin calls behind same-origin facades when possible.


Practical debugging checklist with real examples in mind

After seeing all these real examples of handling CORS errors in front-end applications, a pattern emerges. When something breaks:

  • Check the browser console for the exact CORS message.
  • Inspect the Network tab for:
    • Whether an OPTIONS preflight was sent.
    • Which headers are present in the response (especially Access-Control-Allow-*).
  • From the front-end, log enough metadata (URL, method, whether credentials was used) so backend teams can reproduce the issue.
  • In development, prefer proxies or local API routes so you’re not constantly blocked by remote CORS policies.

For up-to-date reference on browser-side behavior, MDN’s CORS docs are still the gold standard: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS


FAQ: short answers with concrete examples

Q: Can I fix CORS errors entirely in the front-end?
No. The browser enforces CORS based on server response headers. Front-end code can help detect and log issues, or avoid cross-origin calls by using proxies, but real fixes require changing server or gateway configuration.

Q: What’s an example of a simple CORS fix for a front-end app calling a Node API?
A classic example of handling CORS errors in front-end applications is a React app on http://localhost:3000 calling a Node API on http://localhost:4000. Adding app.use(cors({ origin: 'http://localhost:3000' })); in Express, then confirming in the browser that responses include Access-Control-Allow-Origin: http://localhost:3000, usually resolves it.

Q: Are there safe examples of using Access-Control-Allow-Origin: *?
Yes. If your API is public, doesn’t use cookies or other credentials, and only exposes non-sensitive data, you can often set Access-Control-Allow-Origin: *. Many public APIs do this. But if you’re sending cookies or private data, you need specific origins instead of *.

Q: How do I know if a failing request is a CORS issue or just a server bug?
If the browser console mentions CORS headers or blocked responses, and the Network tab shows the response as blocked or opaque, you’re looking at CORS. If you see a clear HTTP status (like 400, 401, 500) and the response body is visible, that’s a regular server bug, not a CORS problem.

Q: Are there examples of tools that help catch CORS misconfigurations?
Yes. API gateways (like AWS API Gateway or Kong) often have CORS plugins or wizards. Browser devtools are still the best first stop, and security projects like OWASP provide guidance and examples on misconfigurations that can either break apps or expose data.

Explore More Implementing CORS in APIs

Discover more examples and insights in this category.

View All Implementing CORS in APIs