CORS Policy Error with React Frontend and Flask Backend When Uploading Multiple Images

Actually I have made frontend in reactJs and backend in python flask(consuming a cnn model for some predictions).When i send like 5 to 6 images as my request, then it is working fine but when i sent 10 to 15 images and some time is exhausting then it is giving error like,although i have setup Cors in my code given below :

192.168.151.24/:1 Access to XMLHttpRequest at 'http://192.168.151.24:2222/upload-images' from origin 'http://192.168.151.24:1111' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.Understand this error
App.js:177 Error uploading files: po {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}code: "ERR_NETWORK"config: {transitional: {…}, adapter: Array(3), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}message: "Network Error"name: "AxiosError"request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}stack: "AxiosError: Network Errorn    at u.onerror (http://192.168.151.24:1111/static/js/main.e4ed8eb8.js:2:404852)n    at La.request (http://192.168.151.24:1111/static/js/main.e4ed8eb8.js:2:412324)n    at async http://192.168.151.24:1111/static/js/main.e4ed8eb8.js:2:441003"[[Prototype]]: Error
overrideMethod @ console.js:288
(anonymous) @ App.js:177
Show 1 more frame
Show lessUnderstand this error
:2222/upload-images:1 
        
Failed to load resource: net::ERR_FAILED

My react Code :

import React, { useEffect, useRef, useState } from 'react';
import { PrimeReactProvider } from 'primereact/api';
import { Toast } from 'primereact/toast';
import { FileUpload } from 'primereact/fileupload';
import { ProgressBar } from 'primereact/progressbar';
import { Button } from 'primereact/button';
import { Tooltip } from 'primereact/tooltip';
import { Tag } from 'primereact/tag';
import { InputSwitch } from 'primereact/inputswitch';
import './App.scss';
import axios from 'axios';
import Box from '@mui/material/Box';
import LinearProgress from '@mui/material/LinearProgress';
import { getCurrentTimestamp, mapRequest } from './UtilityFunctions/pathFunctions';

function App() {
  const toast = useRef(null);
  const [totalSize, setTotalSize] = useState(0);
  const fileUploadRef = useRef(null);
  const [folderPath, setFolderPath] = useState('');
  const [uploadMethod, setUploadMethod] = useState(false);
  const [loading,setLoading] =useState(false);
  // true for "Upload Method", false for "Choose Folder Method"
  const MAX_FILE_SIZE = 50 *1024 * 1024;
  const URL = 'http://192.168.151.24:2222'
  // const URL = 'http://localhost:5000'
  const FIXED_PATH = 'D:\V2_SourceCode\attributesdetection\similar-image-clustering-main\random';
  useEffect(()=>{
    setUploadMethod(uploadMethod)
  },[uploadMethod])
  const onTemplateSelect = (e) => {
    let _totalSize = totalSize;
    let files = e.files;
    let exceeded = false;

    // Calculate total size of selected files
    Object.keys(files).forEach((key) => {
      _totalSize += files[key].size || 0;
      if (_totalSize > MAX_FILE_SIZE) {
        exceeded = true;
      }
    });

    if (exceeded) {
      toast.current.show({ severity: 'error', summary: 'Error', detail: 'Total file size exceeds 50 MB limit for upload feature, use choose folder method for bulk upload !!' });
      fileUploadRef.current.clear(); // Clear selected files if size exceeds limit
    } else {
      setTotalSize(_totalSize);
    }
  };

  const onTemplateUpload = (e) => {
    let _totalSize = 0;

    e.files.forEach((file) => {
      _totalSize += file.size || 0;
    });

    setTotalSize(_totalSize);
    toast.current.show({ severity: 'info', summary: 'Success', detail: 'File Uploaded' });
  };

  const onTemplateRemove = (file, callback) => {
    setTotalSize(totalSize - file.size);
    callback();
  };

  const onTemplateClear = () => {
    setTotalSize(0);
  };

  const headerTemplate = (options) => {
    const { className, chooseButton, uploadButton, cancelButton } = options;
    const value = totalSize / 500000;
    const formattedValue = fileUploadRef && fileUploadRef.current ? fileUploadRef.current.formatSize(totalSize) : '0 B';

    return (
      <div className={className} style={{ backgroundColor: 'transparent', display: 'flex', alignItems: 'center' }}>
        {/* {chooseButton} */}
        <label style={{ marginLeft: '10px' }}>{'Already fixed Folder Method'}</label>
        <InputSwitch
          checked={uploadMethod}
          onChange={(e) => setUploadMethod(e.value)}
          style={{ marginLeft: '10px' }}
        />
        <label style={{ marginLeft: '10px' }}>{'Upload Method'}</label>

        {uploadMethod ? (
          chooseButton
        ) : null}
        {uploadMethod && cancelButton}
        {uploadMethod && <div className="flex align-items-center gap-3 ml-auto">
          <span>{formattedValue} / 50 MB</span>
          <ProgressBar value={value} showValue={false} style={{ width: '10rem', height: '12px' }}></ProgressBar>
        </div>}
      </div>
    );
  };

  const itemTemplate = (file, props) => {
    return (
      uploadMethod && <div className="flex align-items-center flex-wrap pb-5">
        <div className="flex align-items-center" style={{ width: '40%' }}>
          <img alt={file.name} role="presentation" src={file.objectURL} width={100} />
          <span className="flex flex-column text-left ml-3">
            {file.name}
            <small>{new Date().toLocaleDateString()}</small>
          </span>
        </div>
        <Tag value={props.formatSize} severity="warning" className="px-3 py-2" />
        <Button type="button" icon="pi pi-times" className="p-button-outlined p-button-rounded p-button-danger ml-auto" onClick={() => onTemplateRemove(file, props.onRemove)} />
      </div>
    );
  };

  const emptyTemplate = () => {
    console.log(uploadMethod)
    return uploadMethod ? (
      <div className="flex align-items-center flex-column">
        <i className="pi pi-image mt-3 p-5" style={{ fontSize: '5em', borderRadius: '50%', backgroundColor: 'var(--surface-b)', color: 'var(--surface-d)' }}></i>
        <span style={{ fontSize: '1.2em', color: 'var(--text-color-secondary)' }} className="my-5">
          Drag and Drop Image Here
        </span>
      </div>
    ) : (
      <div style={{'display' : 'flex','flexDirection':'column','flexWrap':'nowrap','alignItems':'center','justifyContent':'space-around','gap' : '5rem'}}>
      <div>
        Fixed Path is :  {FIXED_PATH}    
      </div>
            <input
            type="button"
            className='btn btn-success ms-5'
            defaultValue={'Click here to recieve result for fixed folder path'}
            onClick={()=>handlePathSubmit()}
            disabled={loading}
            />
            </div>
    
    ); // If not uploadMethod, return null or alternative content
  };
  

  const handleImagesSubmit = async () => {
    if (fileUploadRef.current) {
      const files = fileUploadRef.current.getFiles();
      if(files.length<1){
        return;
      }
      const formData = new FormData();
      if (!uploadMethod) {
        formData.append('folderPath', folderPath); // Add folder path to form data if using "Choose Folder Method"
      }
      for (let i = 0; i < files.length; i++) {
        formData.append('images', files[i]);
      }
      try {
        setLoading(true);
        // mapRequest('/upload-images')
        const response = await axios.post(`${URL}/upload-images`, formData, {
          headers: {
            'Content-Type': 'multipart/form-data',
       
          },
          maxContentLength: 1000 * 1024 * 1024, // 1000 MB
          maxBodyLength: 1000 * 1024 * 1024, // 1000 MB
          responseType: 'blob', // Set response type to blob to handle file download
        });
        fileUploadRef.current.clear();
        setTotalSize(0); 
        // Create a URL for the downloaded file
        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', `predictions_${getCurrentTimestamp()}.xlsx`);
        document.body.appendChild(link);
        link.click();
      } catch (error) {
        console.error('Error uploading files:', error);
      } finally{
        setLoading(false)
      }
    }
  };
  const handlePathSubmit = async ()=>{
    try {
      setLoading(true);
      const formData = new FormData();
      formData.append('path',FIXED_PATH);
      const response = await axios.post(`${URL}/uploadpath`,formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
   
        },
        responseType: 'blob',
      });

      // Create a URL for the downloaded file
      const url = window.URL.createObjectURL(new Blob([response.data]));
      const link = document.createElement('a');
      link.href = url;
      link.setAttribute('download', `predictions_${getCurrentTimestamp()}.xlsx`);
      document.body.appendChild(link);
      link.click();
    } catch (error) {
      console.error('Error uploading files:', error);
    } finally{
      setLoading(false)
    }
  }

  const chooseOptions = { icon: 'pi pi-fw pi-images', iconOnly: true, className: 'custom-choose-btn p-button-rounded p-button-outlined' };
  const uploadOptions = { icon: 'pi pi-fw pi-cloud-upload', iconOnly: true, className: 'custom-upload-btn p-button-success p-button-rounded p-button-outlined' };
  const cancelOptions = { icon: 'pi pi-fw pi-times', iconOnly: true, className: 'custom-cancel-btn p-button-danger p-button-rounded p-button-outlined' };

  return (
    <PrimeReactProvider>
      <div className="App">
        {loading && 
          <div className='loadingScreen'>
            <div className='loader'>
              <Box sx={{ width: '100%' }}>
                <LinearProgress color="success" />
                <LinearProgress color="success" />
              </Box>
            </div>
            <div className='blockArea'>
              <span>
                Predicting the Values...
              </span>
            </div>
          </div>}
        <Toast ref={toast}></Toast>

        <Tooltip target=".custom-choose-btn" content="Choose" position="bottom" />
        <Tooltip target=".custom-upload-btn" content="Upload" position="bottom" />
        <Tooltip target=".custom-cancel-btn" content="Clear" position="bottom" />

        <FileUpload 
          ref={fileUploadRef} 
          name="demo[]" 
          url="/api/upload" 
          multiple 
          accept="image/*" 
          maxFileSize={10000000}
          onUpload={onTemplateUpload} 
          onSelect={onTemplateSelect} 
          onError={onTemplateClear} 
          onClear={onTemplateClear}
          headerTemplate={headerTemplate} 
          itemTemplate={itemTemplate} 
          emptyTemplate={emptyTemplate}
          chooseOptions={chooseOptions} 
          uploadOptions={uploadOptions} 
          cancelOptions={cancelOptions} 
        />

        {uploadMethod && <div className='footer'>
          <input className='btn btn-success' type='button' defaultValue={'Submit'} onClick={() => handleImagesSubmit()} disabled={loading} />
        </div>}
      </div>
    </PrimeReactProvider>
  );
}

export default App;

My Flask Code :

import os
import io
import json
import numpy as np
import pandas as pd
import tensorflow as tf
from flask import Flask, request, send_file, jsonify
from flask_cors import CORS
from tensorflow.keras.models import load_model
from PIL import Image
from openpyxl import Workbook
from openpyxl.drawing.image import Image as ExcelImage

app = Flask(__name__)
CORS(app)
app.config['MAX_CONTENT_LENGTH'] = 1000 * 1024 * 1024  # 1 GB

# Load the saved models
model_paths = {
    'weave': './saved_model/model.h5',
    'shade': './saved_model/model_shade.h5',
    'majcat': './saved_model/model_majcat.h5',
    'lycra': './saved_model/model_lycra.h5',
    'fabweight': './saved_model/model_fabweight.h5',
    'collar': './saved_model/model_collar.h5',
    'yarn': './saved_model/model_yarn.h5',
    'fab': './saved_model/model_fab.h5',
    'fab2': './saved_model/model_fab2.h5',
    'weave1': './saved_model/model_weave1.h5',
    'weave3': './saved_model/model_weave3.h5',
    'placketchanging': './saved_model/model_placketchanging.h5',
    'bltmainstyle': './saved_model/model_bltmainstyle.h5',
    'substylebelt': './saved_model/model_substylebelt.h5',
    'sleevesmainstyle': './saved_model/model_sleevesmainstyle.h5',
    'btfold': './saved_model/model_btfold.h5',
    'set': './saved_model/model_set.h5',
    'neckband': './saved_model/model_neckband.h5',
    'pocket': './saved_model/model_pocket.h5',
    'fit': './saved_model/model_fit.h5',
    'pattern': './saved_model/model_pattern.h5',
    'length': './saved_model/model_length.h5',
    'mainstyle': './saved_model/model_mainstyle.h5',
    'dcsubstyle': './saved_model/model_dcsubstyle.h5',
    'dcedgeloop': './saved_model/model_dcedgeloop.h5',
    'btnmainmvgr': './saved_model/model_btnmainmvgr.h5',
    'substylebtnclr': './saved_model/model_substylebtnclr.h5',
    'zip': './saved_model/model_zip.h5',
    'zipcol': './saved_model/model_zipcol.h5',
    'addacc': './saved_model/model_addacc.h5',
    'acccol': './saved_model/model_acccol.h5',
    'printtype': './saved_model/model_printtype.h5',
    'printplacement': './saved_model/model_printplacement.h5',
    'printstyle': './saved_model/model_printstyle.h5',
    'patches': './saved_model/model_patches.h5',
    'patchtype': './saved_model/model_patchtype.h5',
    'embroidery': './saved_model/model_embroidery.h5',
    'embtype': './saved_model/model_embtype.h5',
    'placement': './saved_model/model_placement.h5',
    'addacc1': './saved_model/model_addacc1.h5',
    'addwash': './saved_model/model_addwash.h5',
    'addwashcolor': './saved_model/model_addwashcolor.h5'
}

models = {key: load_model(path) for key, path in model_paths.items()}

# Load the mappings
def load_mappings(directory):
    mappings = {}
    for filename in os.listdir(directory):
        if filename.endswith('.json'):
            with open(os.path.join(directory, filename), 'r') as file:
                mapping_name = filename.split('.')[0]
                mappings[mapping_name] = json.load(file)
    return mappings

mappings = load_mappings('mappings')

# Function to preprocess image
def preprocess_image(image):
    image = image.resize((224, 224))
    image_array = np.array(image)
    image_array = np.expand_dims(image_array, axis=0)
    image_array = tf.keras.applications.resnet50.preprocess_input(image_array)
    return image_array

# Function to get image features using ResNet-50
def get_image_features(image_array):
    resnet_model = tf.keras.applications.ResNet50(weights='imagenet', include_top=False, pooling='avg')
    features = resnet_model.predict(image_array)
    return features

# Function to map the predicted indices to labels
def mapToLabels(index, mappings):
    return mappings.get(str(index), "Unknown")

# Function to predict attributes for a given image
def predict_attributes(image):
    image_array = preprocess_image(image)
    image_features = get_image_features(image_array)

    predictions = {}
    for attr, model in models.items():
        prediction = model.predict([image_array, image_features])
        label = mapToLabels(np.argmax(prediction, axis=1)[0], mappings.get(attr, {}))
        predictions[attr] = label

    return predictions

# Function to save images and predictions to Excel
def save_predictions_to_excel(predictions, images):
    columns = ['Filename'] + [f'{attr.capitalize()} Label' for attr in models.keys()]
    df = pd.DataFrame(predictions, columns=columns)

    output = io.BytesIO()
    with pd.ExcelWriter(output, engine='openpyxl') as writer:
        df.to_excel(writer, index=False, sheet_name='Predictions')

        workbook = writer.book
        worksheet = writer.sheets['Predictions']

        # Set column width to fit content including heading length
        for col in worksheet.columns:
            max_length = 0
            column = col[0].column_letter  # Get the column name
            for cell in col:
                try:
                    if cell.row == 1:  # Include header length
                        length = len(str(cell.value))
                    else:
                        length = len(str(cell.value))
                    if length > max_length:
                        max_length = length
                except:
                    pass
            adjusted_width = (max_length + 2)
            worksheet.column_dimensions[column].width = adjusted_width

        for idx, (filename, img) in enumerate(images.items()):
            try:
                img.thumbnail((100, 100))
                image_stream = io.BytesIO()
                img.save(image_stream, format='PNG')
                image_stream.seek(0)
                excel_img = ExcelImage(image_stream)
                cell_location = f'A{idx + 2}'
                worksheet.add_image(excel_img, cell_location)
                worksheet.row_dimensions[idx + 2].height = 100
            except Exception as e:
                print(f"Error processing image {filename}: {e}")

    output.seek(0)
    return output



@app.before_request
def before_request():
    if request.content_length > app.config['MAX_CONTENT_LENGTH']:
        return jsonify({'error': 'File too large'}), 413

@app.route('/upload-images', methods=['POST'])
def upload_images():
    images = request.files.getlist('images')
    predictions = []
    image_data = {}

    for image in images:
        try:
            img = Image.open(image)
            pred_labels = predict_attributes(img)
            predictions.append((image.filename, *pred_labels.values()))
            image_data[image.filename] = img
        except Exception as e:
            print(f"Error processing image {image.filename}: {e}")
            predictions.append((image.filename, *["Unknown"] * len(models)))
            image_data[image.filename] = None

    excel_file = save_predictions_to_excel(predictions, image_data)
    return send_file(excel_file, download_name='predictions.xlsx', as_attachment=True)

@app.route('/uploadpath', methods=['POST'])
def uploadPath():
    folder_path = request.form.get('path')
    if not folder_path:
        return jsonify({'error': 'No folder path provided'}), 400

    if not os.path.isdir(folder_path):
        return jsonify({'error': 'Provided path is not a directory'}), 400

    image_files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]
    predictions = []
    image_data = {}

    for image_file in image_files:
        if image_file.lower().endswith(('png', 'jpg', 'jpeg', 'gif')):
            try:
                with open(os.path.join(folder_path, image_file), 'rb') as img_file:
                    img = Image.open(img_file)
                    pred_labels = predict_attributes(img)
                    predictions.append((image_file, *pred_labels.values()))
                    image_data[image_file] = img
            except Exception as e:
                print(f"Error processing image {image_file}: {e}")
                predictions.append((image_file, *["Unknown"] * len(models)))
                image_data[image_file] = None

    excel_file = save_predictions_to_excel(predictions, image_data)
    output_folder = 'output'
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    backup_file_path = os.path.join(output_folder, 'predictions.xlsx')
    with open(backup_file_path, 'wb') as f:
        f.write(excel_file.getvalue())
    return send_file(excel_file, download_name='predictions.xlsx', as_attachment=True)

@app.route('/', methods=['GET'])
def home():
    return "This is an API for similar detection"

@app.errorhandler(413)
def request_entity_too_large(error):
    return jsonify({'error': 'File too large'}), 413

if __name__ == '__main__':
    app.config['MAX_CONTENT_LENGTH'] = 1000 * 1024 * 1024  # 1 GB
    CORS(app)
    app.run(debug=True)

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật