I am working on a React frontend to chart some data from a fastapi backend. I am using a couple of dropdown components to change the month and year for the requested data. With the initial render the fetch request works fine and returns the data and the charts display. Once I change the dropdowns, I get the following CORS Policy Error in the browser console.
Access to fetch at 'https://fake-url.com/endpoint/' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.
React code snippet with the fetch call:
const [month, setMonth] = useState(1);
const [year, setYear] = useState('2023');
const [revenueData, setRevenueData] = useState({});
useEffect(() => {
const inputs = {
"month": month,
"year": year,
"duration": 1
}
const myHeaders = new Headers();
myHeaders.append("X-API-KEY", "fake-api-key");
myHeaders.append("Content-Type", "application/json");
const requestOptions = {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(inputs),
redirect: 'follow'
};
fetch("https://fake-url.com/endpoint/", requestOptions)
.then(response => response.json())
.then(data => {
setRevenueData((data))
}).catch(error => {
console.log('error', error)
});
}, [month, year]);
I confirmed that I am using CORSMiddleware in fastapi with the following settings:
app.add_middleware(HTTPSRedirectMiddleware)
app.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_methods=['*'],
allow_headers=['*']
)
I also confirmed that the backend is returning access-control headers for preflight with an options request in postman as shown:

UPDATE
The network panel shows that the second request preflight is successful but ultimately fails in an Internal Server Error. Which lead me to:
CORS and Internal Server Error responses

CORS headers are not added when the request ends in an error, that is, when a response is returned with a status code such as 4xx or 5xx.
As shown in the screenshot you provided, when calling the /dashboard_data API endpoint for the third time, the server responds with 500 Internal Server Error response code, indicating that the server encountered an unexpected condition that prevented it from fulfilling the request. Hence, in that case, the server won't include the appropriate Access-Control-Allow-Headers / Access-Control-Allow-Origin headers, and the browser will report a CORS error in the devtools console. Thus, please check what causes the error on server side in the first place and try to fix it (the console running the server should give you insights on that).
Related answers to the concept of CORS issues that might prove helpful to you and future readers can be found here, as well as here and here.
You can resolve this question by the follow code, the solution is add cors manually in exception_handler.
app = FastAPI()
origins = [
"http://localhost",
"http://localhost:8080",
# 其他你希望允许的源
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/")
async def read_root():
return {"message": "Hello World"}
@app.get("/error")
async def create_error():
raise ValueError("This is a test error")
@app.exception_handler(Exception)
async def exception_handler(request: Request, exception: Union[Exception, RuntimeError]):
headers = {
'Access-Control-Allow-Origin': ', '.join(origins),
'Access-Control-Allow-Credentials': 'true',
'Access-Control-Allow-Methods': '*',
'Access-Control-Allow-Headers': '*',
}
if isinstance(exception, EntityException):
response = JSONResponse(
jsonable_encoder(
{
"code": exception.code,
"message": exception.message,
"exception": exception.exception
}
),
headers=headers
)
else:
response = JSONResponse(
jsonable_encoder(
{
"exception": str(exception),
"code": 500,
}
),
headers=headers
)
return response
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With