Search code examples
pythonreactjsaxioscorsfastapi

Sending request from React to FastAPI causes "origin http://localhost:5173 has been blocked by CORS policy" error


I was making a POST request which sends an image file from my UI to the backend server.

Backend Server:

from fastapi import FastAPI, UploadFile
from fastapi.middleware.cors import CORSMiddleware
import numpy as np
import tensorflow as tf
from io import BytesIO
from PIL import Image

app = FastAPI()

origins = ["http://localhost:5173/"]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

model = tf.keras.models.load_model("../models/1")
class_names = ["Normal", "Tuberculosis"]

def convert_image_to_np_array(bytes):
    # Read bytes as PIL image and convert it to np array
    np_array = np.array(Image.open(BytesIO(bytes)))
    return np_array

@app.post("/predict")
async def predict_tuberculosis(file: UploadFile):
    bytes = await file.read()
    np_array = convert_image_to_np_array(bytes)
    batch_image = np.expand_dims(np_array, axis=0)
    resized_batch_image = np.resize(batch_image, (1,256,256,3))
    prediction = model.predict(resized_batch_image)
    label = class_names[np.argmax(prediction)]
    accuracy = np.max(prediction)
    print(accuracy)
    return label

Frontend:

import React from "react"
import { useState } from "react"
import axios from "axios"
import "./App.css"

function App() {
  function callPrediction(file) {
    const formData = new FormData()
    formData.append("file", file)
    axios.post("http://localhost:8000/predict", formData)
    .then(res => setResult(res.data))
    .catch(err => console.log(err))
  }

  ...

Note: The file input from callPrediction has the format like this

enter image description here

When I call the function callPrediction to send an image file as an input to the function predict_tuberculosis , I got this error popping up

enter image description here

I did go searching for this but all the solutions I got was just adding CORS to my backend (which I have already done).

I really appreciate any helps! Thank you


Solution

  • You should remove the trailing slash from the origin URL in:

    http://localhost:5173/
                         ^
    

    The origin URL should instead look like this http://localhost:5173. Hence:

    origins = ["http://localhost:5173"]
    
    app.add_middleware(
        CORSMiddleware,
        allow_origins=origins,
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
    

    For further details, please have a look at the following answers here, here, as well as here, here and here.