Не удается загрузить изображение с интерфейса React на серверную часть flask

#python #reactjs #flask #flask-sqlalchemy

Вопрос:

Я пытаюсь загрузить изображение из React на серверную часть flask вместе с некоторой другой информацией в форме. Когда я утешаю.войдите в систему, чтобы просмотреть данные на стороне интерфейса, они работают нормально, но когда я печатаю данные на внутренней стороне, они не возвращают ничего. Кстати, я совершенно новичок в React и flask, так что код может быть немного грязным.

server.py

 @app.route('/api/other',methods=["POST"])
def post_other():
    json_data = request.get_data().decode('utf-8')
    data = json.loads(json_data)
    new_order = line_order(product_type="other",weight=data["weight"],note=data["note"],picture_uuid=data["uuid"],order_status="ordered",create_uid=data["userId"])
    db.session.add(new_order)
    db.session.commit()
    return {'state':'00'}

@app.route("/api/other_img",methods=["POST"])
def post_Other_img():
    data = request.files.get('pic')
    print(data)
    file_name = data.filename
    data.save(os.path.join("/public/static/img/",file_name ".png"))
    return {"state":"00"}
 

React.js (получение) Отредактировано

 var formData = new FormData();
const changeHandler = (event) => {  
      setSelectedFile(event.target.files[0])
      formData.append("pic",event.target.files[0],uuid ".png")
      for (var pair of formData.entries()) {
        console.log(pair[0]  ', '   pair[1]); //This return pic,[object File]
    }
    };
    function handleSave(event){
          event.preventDefault();
            const info = {weight,note,uuid,userId}
            const response = fetch('https://something/api/other',{
              method:'POST',
              mode:"cors"
              ,headers:{
                'Content-Type':'application/json'
              },
              body:JSON.stringify(info)
            }).then(fetch(
              'https://something/api/other_img',
              {
                method: 'POST',
                body: formData,
                mode:"no-cors",
              }
            )
              .then((response) => response.json())
              .then((result) => {
                console.log('Success:', result);
              })
              .catch((error) => {
                console.error('Error:', error);
              }) ).then(history.push('/preview'))
        }
 

React.js (возвращение)

  return(
        <div className="container">
            <h1>Picture Page</h1>
            <form method="post" onSubmit={handleSave} encType="multipart/form-data">
                <p>weight:</p>
                <div onChange={handleWeight}>
                    <label>
                        <input type="radio" name="weight" value="ones"></input>
                        <span>1 s</span>
                    </label>
                    <label>
                        <input type="radio" name="weight" value="oneb"></input>
                        <span>1 b</span>
                    </label> 
                </div>
                
                <label>image:</label>
                <div className = "file-field input-field">
                    <div className = "btn">
                        <span>Browse</span>
                        <input name="pic" id="pic" type="file" onChange={changeHandler} />
                    </div>
                    
                    <div className = "file-path-wrapper">
                        <input className = "file-path validate" type = "text" placeholder = "Upload a file" />
                    </div>
                </div>    
                <div className="input-field col s6">
                    <input id="note"type="text" name="note" onChange={handleNote} className="validate" onFocus={handlefocusnote} onBlur={handleblurnote}></input>
                    <label className={focusnote} htmlFor="note">Note:</label>
                </div>
                <br></br>
                <input type="submit" value="Save" className="waves-effect waves-light btn"></input>
            </form>
        </div>
        
    )
 

и это ошибка, которую я получаю из колбы

 Traceback (most recent call last):
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 2088, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.handle_exception(e)
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask_cors/extension.py", line 165, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 2070, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 1515, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask_cors/extension.py", line 165, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 1513, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/dolineorder/.pyenv/versions/3.9.5/envs/sgjorder/lib/python3.9/site-packages/flask/app.py", line 1499, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/home/dolineorder/sgjorder/server.py", line 114, in post_Other_img
    file_name = data.filename
AttributeError: 'NoneType' object has no attribute 'filename'
 

Примечание : в этом коде для стилизации используется материализованный css.

Ответ №1:

Проблема

В вашем разделе React после выполнения первого запроса GET API второй запрос POST API использует переменную formData , называемую значением формы, которое не определено.

 .then(fetch(
     'https://something/api/other_img',
     {
        method: 'POST',
        body: formData, // undefined
        mode:"no-cors",
     }
)
 

И вот почему, когда вы делаете запрос post_Other_img , данные `Отсутствуют

 @app.route("/api/other_img",methods=["POST"])
def post_Other_img():
    data = request.files.get('pic') # This is None
 

Решение

Убедитесь, что formData это определено в React. Также поместите файл изображения в данные формы, и он должен быть назван pic в данных формы, потому что вы получаете доступ request.file.get('pic') в колбе.

Я не могу дать вам конкретное решение, потому что вы не указали, откуда поступают данные вашей формы и как они отформатированы. Но, по крайней мере, ты знаешь, в чем дело. Если вам нужна дополнительная помощь, пожалуйста, прокомментируйте этот ответ и укажите все, начиная с того, откуда вы хотите получить formData изображение и где оно находится.

Комментарии:

1. О, я забыл включить эту часть в вопрос. Я снова отредактирую вопрос

2. @SorawitC Вам, вероятно, следует добавить a Content-type в заголовок вашего запроса на публикацию. Content-Type: multipart/form-data

3. Здравствуйте @DevGuyAhnaf, я не знаю, как реагировать, у меня очень ограниченные знания. Однако я знаю фляжку. Я создал некоторый код для загрузки, и бэкэнд успешно работает. Я получил фрагмент кода из Интернета для части react. Я смог изменить это и заставить его работать. Он загружает изображения, но не может загружать несколько изображений. Могу загрузить только один. Ты можешь помочь мне разобраться в моих ошибках?