FastAPI error: No "Access-Control-Allow-Origin" header is present on the requested resource
David Y.
—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:
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?
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.
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:
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:
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
.
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:
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.
Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.
SEE EPISODESConsidered “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.
Here’s a quick look at how Sentry handles your personal information (PII).
×We collect PII about people browsing our website, users of the Sentry service, prospective customers, and people who otherwise interact with us.
What if my PII is included in data sent to Sentry by a Sentry customer (e.g., someone using Sentry to monitor their app)? In this case you have to contact the Sentry customer (e.g., the maker of the app). We do not control the data that is sent to us through the Sentry service for the purposes of application monitoring.
Am I included?We may disclose your PII to the following type of recipients:
You may have the following rights related to your PII:
If you have any questions or concerns about your privacy at Sentry, please email us at [email protected].
If you are a California resident, see our Supplemental notice.