Unable to extract image file uploaded on React frontend on Flask backend

…衆ロ難τιáo~ 提交于 2019-12-24 10:42:28

问题


I'm trying to send an image file(that resides locally) from my react single page frontend app to my flask backend. Some of the things I have tried out but not limited to are capturing my content type and indicating the encType on the front end. Although, the post requests indicates that it was successful. However, when I log the requests.files, request.form, request.values, I get no data input. Obviously, there's something I'm missing out and could really use any help I could get from anyone. Thanks

FrontEnd:

import React, { Component } from 'react';
import axios from 'axios';
import logo from './logo.svg';
import './App.css';
// const qs = require('querystring');

class App extends Component {
  constructor(props){
    super();
    this.state = { imagePreviewUrl: '', file: '' };

    this._handleSubmit = this._handleSubmit.bind(this);
    this._handleImageChange = this._handleImageChange.bind(this);
    this.uploadImage = this.uploadImage.bind(this);
  }

  _handleImageChange(e){
    e.preventDefault();
    let file = e.target.files[0];
    let reader = new FileReader();
    reader.onloadend = () => {
      this.setState({ file: file,
                      imagePreviewUrl: reader.result });
    }
    reader.readAsDataURL(file);
  }

  _handleSubmit(e){
    e.preventDefault();
    console.log("file value before this.uploadImage call:",this.state.file);
    this.uploadImage(this.state.file);

  }

  uploadImage(filepath){

      let imageFormData = new FormData();
      imageFormData.append('filepath', filepath, filepath.name);
      let newHeaders = new Headers({
              "Content-type": "image/png"
            });
      console.log("checking if imageFormData has value:",imageFormData.has('filepath'));
        return axios.post('/add', newHeaders, imageFormData)
          .then((response) => {
            console.log("response:", response);
          })
          .catch((err) => {
            console.log("error:", err);
          });

    }


  render() {

    let { imagePreviewUrl } = this.state;
    let $imagePreview = null
    if (imagePreviewUrl){
      $imagePreview = ( <img src={imagePreviewUrl} />);
    }
    else {
      $imagePreview = (<div className="previewText">Please select an Image for Preview</div>);
    }
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <form onSubmit={this._handleSubmit}>
          <div>
            <label htmlFor="image_uploads">Choose images to upload (PNG, JPG)</label>
            <input type="file" id="image_uploads" name="filepath" encType="multipart/form-data" onChange={this._handleImageChange}/>
          </div>
          <div>
            <button type='submit'>Submit</button>
          </div>
        </form>
        <div>
        {$imagePreview}
        </div>
      </div>
    );
  }
}

export default App;

Backend:

from flask import Flask, request, render_template, send_from_directory

gunicorn_error_logger = logging.getLogger('gunicorn.error')
app.logger.handlers.extend(gunicorn_error_logger.handlers)
app.logger.setLevel(logging.DEBUG)
app = Flask(__name__)


@app.route('/', methods=['GET'])
def root():
    app.logger.debug("Inside root route")
    return render_template('index.html')

@app.route('/add', methods=['POST'])
def add_handler():
    app.logger.debug("Inside add route")
    app.logger.debug("Request Params: {}".format(request))
    app.logger.debug("Values: {}".format(request.values))
    app.logger.debug("Form: {}".format(request.form))
    app.logger.debug("Files: {}".format(request.files))

    return "got it"

回答1:


I had the same kind of issue trying to send a sound blob to the server. Data is received and can be seen by calling request.get_data() if you call only this method on request (see : https://stackoverflow.com/a/23898949/1058203). However, I found no easy way to parse this data in a correct way. What worked for me :

First convert blob to base64 on client, and ship to server as Json :

var reader = new FileReader();
reader.readAsDataURL(blob); 
reader.onloadend = function() {
  var base64audio = reader.result;
  // may not apply or differ in your case
  var prefixToDrop = 'data:audio/wav;base64,';
  var base64audioCut = base64audio.substring(prefixToDrop.length);
  callbackFn(base64audioCut)
};

Ship to backend in callback using JQuery :

$.ajax({
        type: 'POST',
        url: '/receiveAudio',
        data: JSON.stringify({
          "type": "wav",
          "base64audio" : base64audioCut
        }),
        dataType:"json",
        processData: false,
        contentType: "application/json;",
        success: function(x){...},
        error: function(x){...},
        processData: false
});

Backend :

@app.route('/receiveAudio', methods=['POST'])
def receiveAudio():
    dataKey = 'base64audio'
    json = request.get_json()

    if not dataKey in json:
        return abort(400, "Missing 'base64audio' key")

    base64_decoded = base64.b64decode(json[dataKey])


来源:https://stackoverflow.com/questions/45641827/unable-to-extract-image-file-uploaded-on-react-frontend-on-flask-backend

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!