Connecting React Dropzone Uploader and Flask

Viewed 457

I want to get react-dropzone-uploader to connect with my Flask backend and to send the file (image) via a form to the backend. But I have problems accessing the uploaded image. The server responds with: "400 Bad Request: The browser (or proxy) sent a request that this server could not understand." How do I access the uploaded image from the React component to the backend?

Flask route for the image upload request:

    @app.route("/sell", methods=['GET', 'POST'])
def sell():
    if session.get("user_id") is None:
        return render_template("register.html")

    if request.method == 'POST':
        print(request)
        try:            
            brand = request.form.get("brand")
            model = request.form.get("model")
            condition = request.form.get("condition")
            gender = request.form.get("gender")
            year = request.form.get("year")
            movement = request.form.get("movement")
            price = request.form.get("price")
            description = request.form.get("description") 
            created = datetime.now().isoformat()
        
            with sql.connect("mydb.db") as con:
                cur = con.cursor()
                cur.execute("INSERT INTO items (brand, model, condition, gender, year, movement, price, description, created, item_owner) VALUES (?,?,?,?,?,?,?,?,?,?)", (brand, model, condition, gender, year, movement, price, description, created, session["user_id"]))
                file_entry = query_db('SELECT last_insert_rowid()')
                image = request.files['file']

                # flask image upload procedure from https://pythonise.com/series/learning-flask/flask-uploading-files
                if image:                
                    # Check if the image has a name
                    if image.filename == "":
                        return render_template("/sell.html", msg = "Selected image has no name")

                    if allowed_image(image.filename):
                        filename = ''.join(random.choices(string.ascii_lowercase + string.ascii_uppercase + string.digits, k=8)) + secure_filename(image.filename) 
  
                        image.save(os.path.join(app.config["IMAGE_UPLOADS"], filename))


                    cur.execute("INSERT INTO images (item, user, date, path) VALUES (?,?,?,?)", (1, session["user_id"], created, "/static/images/{}".format(filename)))

            
            con.commit()

            return render_template("watch.html", item_id = 14)
            con.close()

React code

    import React from "react";
import ReactDOM from "react-dom";
import 'react-dropzone-uploader/dist/styles.css';
import Dropzone from 'react-dropzone-uploader';

const ImageAudioVideo = () => {
    const getUploadParams = ({ meta }) => {
      const url = 'http://127.0.0.1:5000/sell'
      return { url, meta: { fileUrl: `${url}/${encodeURIComponent(meta.name)}` } }
    }
  
    const handleChangeStatus = ({ meta }, status) => {
      console.log(status, meta)
    }
  
    const handleSubmit = (files, allFiles) => {
      console.log(files.map(f => f.meta))
      allFiles.forEach(f => f.remove())
    }
  
    return (
      <Dropzone
        getUploadParams={getUploadParams}
        onChangeStatus={handleChangeStatus}
        onSubmit={handleSubmit}
        accept="image/*,audio/*,video/*"
        inputContent={(files, extra) => (extra.reject ? 'Image, audio and video files only' : 'Drag Files')}
        styles={{
          dropzoneReject: { borderColor: 'red', backgroundColor: '#DAA' },
          inputLabel: (files, extra) => (extra.reject ? { color: 'red' } : {}),
        }}
      />
    )
  }
  
<ImageAudioVideo />

const rootElement = document.getElementById("react-root");
ReactDOM.render(<ImageAudioVideo />, rootElement);
1 Answers

Your server is probably not configured to respond to CORS requests.

react-dropzone-uploader performs an OPTIONS request before upload. You can simply enable this with the Flask CORS module.

Just initialising the CORS module with the app will decorate all routes with CORS and it should work.

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)
Related