Sentry Answers>FastAPI>

FastAPI error: No "Access-Control-Allow-Origin" header is present on the requested resource

FastAPI error: No "Access-Control-Allow-Origin" header is present on the requested resource

David Y.

The Problem

I’m developing a web application with a FastAPI backend and a JavaScript frontend. But whenever I make a request from the frontend to the backend using fetch in JavaScript, I get an error that looks like this:

Click to Copy
Access to fetch at 'http://localhost:8000/get-main-query-data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

What is happening here and how do I allow my application’s frontend to communicate with the backend?

The Solution

By default, modern browsers block attempts by website frontends to communicate across domains. So, for example, JavaScript served by https://sentry.io will not be able to fetch resources from https://example.com. Likewise, your frontend on http://localhost:3000 cannot interact with the API on http://localhost:8000. This is a security measure to prevent malicious websites from interacting with legitimate websites – for example, if you’re logged into your banking website on one tab and visit an untrustworthy website in another tab, that second website will not be able to interact with your banking website. This is called the same-origin policy.

Depending on your architecture, you may want to comply with this same-origin policy or use cross-origin resource sharing (CORS) to make exceptions to it. Both approaches are detailed below.

Complying With the same-origin Policy

The simplest way to avoid CORS errors is to place the frontend and backend on the same domain. Having both frontend and backend as part of the same application will likely be the intended production deployment in any case. To achieve this, you can serve the application frontend as static files from FastAPI itself. For example, you can add the following to your FastAPI code:

Click to Copy
from fastapi import FastAPI from fastapi.staticfiles import StaticFiles app = FastAPI() # ... FastAPI routes ... app.mount("/", StaticFiles(directory="static", html=True), name="static")

You can then place the application’s frontend HTML in the static directory. Assuming you have a file named index.html, it will be accessible at http://localhost:8000/, along with any other HTML files you’ve added. Requests made by fetch in these files will now be able to access FastAPI routes from the same origin and will no longer invoke CORS errors.

When serving static files from the root (/) endpoint in this manner, all FastAPI endpoints should be defined first. This is because app.mount will handle all requests starting with the specified path (in this case "/") from the point where it is defined. To avoid this, you could alternatively serve static files from a subdirectory:

Click to Copy
from fastapi import FastAPI from fastapi.staticfiles import StaticFiles app = FastAPI() # ... FastAPI routes ... app.mount("/app", StaticFiles(directory="static", html=True), name="static")

Under this configuration, index.html in the static folder will be served at http://localhost:8000/app.

Sharing Resources Across Origins

Cross-Origin Resource Sharing (CORS) is a mechanism for making selective exceptions to the same-origin policy in instances where there are legitimate requirements for cross-domain requests. For example, if your JavaScript frontend and FastAPI backend are intended to run on different domains in production, you can set up a CORS policy that allows them to communicate with each other, without completely disabling the same-origin policy.

CORS depends on HTTP headers returned by the backend. To send these headers in your FastAPI application, you can use CORSMiddleware. For example:

Click to Copy
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() # You can add additional URLs to this list, for example, the frontend's production domain, or other frontends. allowed_origins = [ "http://localhost:3000" ] app.add_middleware( CORSMiddleware, allow_origins=allowed_origins, allow_credentials=True, allow_methods=["GET", "POST", "PUT", "DELETE"], allow_headers=["X-Requested-With", "Content-Type"], )

With this configuration in place, the frontend at http://localhost:3000 will be able to issue requests to and receive responses from the FastAPI application. This will still work even if you change the domain of the FastAPI application.

Note that CORS errors may still appear if FastAPI experiences a 500 error, as these errors terminate the request before the CORS middleware can add any HTTP headers to the response.

  • Syntax.fmListen to the Syntax Podcast
  • Community SeriesIdentify, Trace, and Fix Endpoint Regression Issues
  • ResourcesBackend Error Monitoring 101
  • Syntax.fm logo
    Listen to the Syntax Podcast

    Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.

    SEE EPISODES

Considered “not bad” by 4 million developers and more than 100,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.

© 2024 • Sentry is a registered Trademark of Functional Software, Inc.