最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - Sending request from React to FastAPI causes a CORS policy error - Stack Overflow

programmeradmin1浏览0评论

When I send a fetch request from the frontend server (React) to the backend server (FastAPI), an error occurs:

localhost/:1 Access to fetch at 'http://localhost:8000/predict/' 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.

Environment:

  • Windows 11
  • React 19.1.0
  • uvicorn 0.34.0
  • Python 3.12.4

Frontend:

import React from "react";
import { useForm } from "react-hook-form";
import { useMutation } from "@tanstack/react-query";

interface FormSchema {
  mean_radius: number;
  mean_texture: number;
  mean_perimeter: number;
  mean_area: number;
}

interface PredictionResponse {
  prediction: number;
}

const Frontend = () => {
  const { register, handleSubmit } = useForm<FormSchema>({
    defaultValues: {
      mean_radius: 0,
      mean_texture: 0,
      mean_perimeter: 0,
      mean_area: 0,
    },
  });

  // Mutation for sending data to the backend
  const mutation =  useMutation<PredictionResponse, Error, FormSchema>({
    mutationFn: async (formData: FormSchema) => {
    const response = await fetch("http://localhost:8000/predict/", {
      method: "POST",
      credentials: 'include',
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(formData),
    });

    if (!response.ok) {
      throw new Error("Failed to fetch");
    }

    return response.json();
  }
  });

  const onSubmit = (data: FormSchema) => {
    mutation.mutate(data);
  };

  return (
    <div>
      <h1>React + FastAPI Example</h1>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div>
          <label>Mean Radius:</label>
          <input type="number" {...register("mean_radius")} />
        </div>
        <div>
          <label>Mean Texture:</label>
          <input type="number" {...register("mean_texture")} />
        </div>
        <div>
          <label>Mean Perimeter:</label>
          <input type="number" {...register("mean_perimeter")} />
        </div>
        <div>
          <label>Mean Area:</label>
          <input type="number" {...register("mean_area")} />
        </div>
        <button type="submit">Predict</button>
      </form>

      {/* Display loading, error, or success states */}
      {mutation.isError && (
        <p>Error occurred: {(mutation.error as Error).message}</p>
      )}
      {mutation.isSuccess && (
        <p>Prediction Result: {mutation.data?.prediction}</p>
      )}
    </div>
  );
};

export default Frontend;

Backend:

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

app = FastAPI()

# Define the data schema
class TestData(BaseModel):
    mean_radius: float
    mean_texture: float
    mean_perimeter: float
    mean_area: float

# Configure CORS settings
origins = [
    "http://localhost:3000",  # React frontend
    "http://127.0.0.1:3000"
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,  # Allow requests from specific origins
    allow_credentials=True,  # Allow cookies and credentials if needed
    allow_methods=["*"],  # Allow all HTTP methods (GET, POST, etc.)
    allow_headers=["*"],  # Allow all headers
)

@app.post("/predict/")
def do_predict(data: TestData):
    # Example processing logic (replace with actual logic)
    result = data.mean_radius + data.mean_texture + data.mean_perimeter + data.mean_area
    return {"prediction": result}

How I started servers:

npm start
uvicorn maintest:app --reload --host 0.0.0.0 --port 8000

I checked:

  • Sending request from React to FastAPI causes "origin http://localhost:5173 has been blocked by CORS policy" error
  • Access from origin '' has been blocked even though I've allowed /
  • React not showing POST response from FastAPI backend application
  • Sending POST request to FastAPI app running on localhost using JavaScript Fetch API
  • FastAPI is not returning cookies to React frontend
  • How to redirect from one domain to another and set cookies or headers for the other domain?
  • How to access FastAPI backend from a different machine/IP on the same local network?
  • FastAPI: How to enable CORS only for specific endpoints?

python log

INFO:     Stopping reloader process [64148]
PS E:\workspace\Python\tmp\front-back-end\backend> uvicorn maintest:app --reload --host 0.0.0.0 --port 8000
INFO:     Will watch for changes in these directories: ['E:\\workspace\\Python\\tmp\\front-back-end\\backend']
INFO:     Uvicorn running on :8000 (Press CTRL+C to quit)
INFO:     Started reloader process [33768] using WatchFiles
ERROR:    Error loading ASGI app. Attribute "app" not found in module "maintest".
WARNING:  WatchFiles detected changes in 'maintest.py'. Reloading...
INFO:     Started server process [73580]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

When I send a fetch request from the frontend server (React) to the backend server (FastAPI), an error occurs:

localhost/:1 Access to fetch at 'http://localhost:8000/predict/' 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.

Environment:

  • Windows 11
  • React 19.1.0
  • uvicorn 0.34.0
  • Python 3.12.4

Frontend:

import React from "react";
import { useForm } from "react-hook-form";
import { useMutation } from "@tanstack/react-query";

interface FormSchema {
  mean_radius: number;
  mean_texture: number;
  mean_perimeter: number;
  mean_area: number;
}

interface PredictionResponse {
  prediction: number;
}

const Frontend = () => {
  const { register, handleSubmit } = useForm<FormSchema>({
    defaultValues: {
      mean_radius: 0,
      mean_texture: 0,
      mean_perimeter: 0,
      mean_area: 0,
    },
  });

  // Mutation for sending data to the backend
  const mutation =  useMutation<PredictionResponse, Error, FormSchema>({
    mutationFn: async (formData: FormSchema) => {
    const response = await fetch("http://localhost:8000/predict/", {
      method: "POST",
      credentials: 'include',
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(formData),
    });

    if (!response.ok) {
      throw new Error("Failed to fetch");
    }

    return response.json();
  }
  });

  const onSubmit = (data: FormSchema) => {
    mutation.mutate(data);
  };

  return (
    <div>
      <h1>React + FastAPI Example</h1>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div>
          <label>Mean Radius:</label>
          <input type="number" {...register("mean_radius")} />
        </div>
        <div>
          <label>Mean Texture:</label>
          <input type="number" {...register("mean_texture")} />
        </div>
        <div>
          <label>Mean Perimeter:</label>
          <input type="number" {...register("mean_perimeter")} />
        </div>
        <div>
          <label>Mean Area:</label>
          <input type="number" {...register("mean_area")} />
        </div>
        <button type="submit">Predict</button>
      </form>

      {/* Display loading, error, or success states */}
      {mutation.isError && (
        <p>Error occurred: {(mutation.error as Error).message}</p>
      )}
      {mutation.isSuccess && (
        <p>Prediction Result: {mutation.data?.prediction}</p>
      )}
    </div>
  );
};

export default Frontend;

Backend:

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

app = FastAPI()

# Define the data schema
class TestData(BaseModel):
    mean_radius: float
    mean_texture: float
    mean_perimeter: float
    mean_area: float

# Configure CORS settings
origins = [
    "http://localhost:3000",  # React frontend
    "http://127.0.0.1:3000"
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,  # Allow requests from specific origins
    allow_credentials=True,  # Allow cookies and credentials if needed
    allow_methods=["*"],  # Allow all HTTP methods (GET, POST, etc.)
    allow_headers=["*"],  # Allow all headers
)

@app.post("/predict/")
def do_predict(data: TestData):
    # Example processing logic (replace with actual logic)
    result = data.mean_radius + data.mean_texture + data.mean_perimeter + data.mean_area
    return {"prediction": result}

How I started servers:

npm start
uvicorn maintest:app --reload --host 0.0.0.0 --port 8000

I checked:

  • Sending request from React to FastAPI causes "origin http://localhost:5173 has been blocked by CORS policy" error
  • Access from origin 'https://example' has been blocked even though I've allowed https://example/
  • React not showing POST response from FastAPI backend application
  • Sending POST request to FastAPI app running on localhost using JavaScript Fetch API
  • FastAPI is not returning cookies to React frontend
  • How to redirect from one domain to another and set cookies or headers for the other domain?
  • How to access FastAPI backend from a different machine/IP on the same local network?
  • FastAPI: How to enable CORS only for specific endpoints?

python log

INFO:     Stopping reloader process [64148]
PS E:\workspace\Python\tmp\front-back-end\backend> uvicorn maintest:app --reload --host 0.0.0.0 --port 8000
INFO:     Will watch for changes in these directories: ['E:\\workspace\\Python\\tmp\\front-back-end\\backend']
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [33768] using WatchFiles
ERROR:    Error loading ASGI app. Attribute "app" not found in module "maintest".
WARNING:  WatchFiles detected changes in 'maintest.py'. Reloading...
INFO:     Started server process [73580]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
Share Improve this question edited Mar 31 at 2:56 dixhom asked Mar 30 at 10:38 dixhomdixhom 3,0454 gold badges23 silver badges39 bronze badges 7
  • Are you getting any error messages in your FastAPI terminal? HTTP 500 responses don't set the Access-Control-Allow-Origin header, so some browsers will display that as a CORS error. – M.O. Commented Mar 30 at 13:05
  • I got the error in my console in the Chrome browser. – dixhom Commented Mar 30 at 14:41
  • Does this answer your question? – Chris Commented Mar 30 at 16:40
  • @dixhom That was not my question. Are you also getting an error in FastAPI? What do the Python logs look like? – M.O. Commented Mar 30 at 19:19
  • @M.O. See "When I send a fetch request from the frontend server" If we are talking about the "frontend" being the browser ("I got the error in my console in the Chrome browser."), the browser sends a preflight OPTIONS request first for POST requests that has to be handled to avoid the error in the browser. See stackoverflow/questions/42311018/…. Doesn't really matter what the server or programming language is that handles the OPTIONS request. – guest271314 Commented Mar 30 at 19:25
 |  Show 2 more comments

3 Answers 3

Reset to default 0

Change the port number in React code and uvicorn command. Surprisingly, it worked. Perhaps after killning the uvicorn by Ctrl+C, zombie processes remained behind the console.

If you are making a request from the browser you have to handle the OPTIONS preflight request. See Why does Fetch API Send the first PUT request as OPTIONS.

Something like this

if (request.method === "OPTIONS") {
  return new Response(null, {
    headers: {
      "Cache-Control": "no-cache",
      "Content-Type": "text/plain; charset=UTF-8",
      "Cross-Origin-Opener-Policy": "unsafe-none",
      "Cross-Origin-Embedder-Policy": "unsafe-none",
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Private-Network": "true",
      "Access-Control-Allow-Headers": "Access-Control-Request-Private-Network",
      "Access-Control-Allow-Methods": "OPTIONS,POST,GET,HEAD,QUERY,query",
    }
  })
}

if (request.method === "POST") {
  // Do stuff
}

if (request.method === "GET") {
  // Do stuff
}

This is a very beginner level mistake I would say please check your CORS origin list carefully.

Make sure your frontend and backend domain matches properly, for example http://localhost:9000 and http:127.0.0.1:9000 is not same according to the cors origin list. Also there should be no slash at the end of your domain.

origins = [
    "http://localhost:3000",  # React frontend
    "http://127.0.0.1:3000"
]

For safety reason do something like this ->

origins = [
    "http://localhost",  # React frontend
    "http://127.0.0.1",  # React frontend
    "http://localhost:3000", # React frontend
    "http://127.0.0.1:3000"  # React frontend
]
发布评论

评论列表(0)

  1. 暂无评论