FastAPI + CORS: A Quick Solution to Cross-Origin Resource Sharing Issues

What is the CORS Problem?

When frontend code (e.g., JavaScript in a web page) requests a backend API from a different domain, port, or protocol, the browser automatically blocks the request due to the security policy (Same-Origin Policy). This is known as the “CORS problem.”

For example:
- The frontend is deployed at http://localhost:3000 (e.g., a Vue/React project).
- The backend API runs at http://localhost:8000 (a FastAPI service).
- When the frontend uses fetch or axios to call the backend, the browser throws an error like “Cross-origin request blocked.”

Why Does FastAPI Have CORS Issues by Default?

FastAPI does not automatically handle cross-origin requests. When the frontend and backend are “not same-origin,” the browser rejects the response. This is a browser security mechanism to prevent malicious websites from accessing data from other sites.

How to Solve CORS Issues with FastAPI?

The core solution is to add CORS (Cross-Origin Resource Sharing) middleware to the backend, telling the browser “which frontend domains can access my API.” FastAPI implements this via CORSMiddleware.

Step 1: Install Dependencies (Built-in in FastAPI)

FastAPI natively includes CORSMiddleware—no additional installation is needed. Just import it.

Step 2: Configure CORS Middleware

Add the CORS middleware to your FastAPI application to allow specified frontend domains, HTTP methods, and headers.

Code Example:

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

app = FastAPI()

# Add CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # Allows all frontend domains (for development only)
    allow_credentials=True,  # Allows cookies in cross-origin requests
    allow_methods=["*"],  # Allows all HTTP methods (GET, POST, etc.)
    allow_headers=["*"],  # Allows all request headers
)

# Define a test API endpoint
@app.get("/api/hello")
async def read_hello():
    return {"message": "Hello, CORS!"}

Key Parameter Explanations

Parameter Name Purpose Example (Common in Development)
allow_origins List of frontend domains allowed to access the API (must be full URLs) ["*"] (allow all, for development)
allow_methods Allowed HTTP methods (GET, POST, etc.) ["GET", "POST", "OPTIONS"]
allow_headers Allowed request headers (e.g., custom headers like X-Token) ["*"] (allow all headers)
allow_credentials Whether to allow cookies in cross-origin requests (e.g., withCredentials: true) False (default in development)

Important Notes

  1. Avoid ["*"] in Production:
    allow_origins=["*"] allows all domains, which is insecure for production. Specify exact domains instead:
   allow_origins=["https://your-frontend.com"]  # Only allow this domain
  1. allow_credentials and allow_origins:
    If the frontend uses withCredentials: true (to send cookies), allow_origins cannot use ["*"] and must be a specific domain.

Frontend Request Example

After configuring CORS, the frontend can call the API without errors:

// Frontend code (HTML/JS file)
async function fetchData() {
  try {
    const response = await fetch("http://localhost:8000/api/hello");
    const data = await response.json();
    console.log("Backend response:", data);
  } catch (error) {
    console.error("CORS request failed:", error);
  }
}

fetchData();

Result: If CORS is configured correctly, the frontend console will print {"message": "Hello, CORS!"} with no errors.

Summary

CORS issues stem from browser security restrictions. FastAPI solves this with CORSMiddleware. Configure allow_origins, allow_methods, etc., to let frontend requests work. Use ["*"] for testing, but restrict domains in production for security.

With these steps, you can handle CORS in FastAPI and build secure, cross-origin-compatible applications!

Xiaoye