Home > Net >  Axios Error on file upload from react to flask
Axios Error on file upload from react to flask

Time:12-09

I'm trying to upload a CSV File from React to my Flask backend. My code is shown below. With the code below, the Flask returns 400 (Axios Error).

When I change the Flask to print(request.files), it prints ImmutableDict([]) and it doesn't seem to have any data (I think so..)

Error:

AxiosError {message: 'Request failed with status code 400', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpReques

App.js:

    let handleSubmit = async (e) => {
        e.preventDefault()
        let file = csvFile
        const formData = new FormData()

        formData.append("file", file)

        axios
            .post("http://127.0.0.1:5000/reactTest", formData)
            .then((res) => console.log(res))
            .catch((err) => console.warn(err))

...

<input 
type='file'
value={csvFile}
name='csvFile'
/>
<button type='submit' onClick={handleSubmit}></button>

api.py:

@app.route('/reactTest', methods=['POST'])
def reactTest():
    if request.method == 'POST':
        # print(request.files)
        print(request.files['file'])
        return {'status': 200}

CodePudding user response:

<input type="file"> cannot be a controlled component because you cannot set the value due to browser security restrictions.

Instead, treat it as an uncontrolled component. You can even just pass an HTMLFormElement into FormData to capture all inputs.

const [hasFiles, setHasFiles] = useState(false);

const handleSubmit = async (e) => {
  e.preventDefault();
  const formData = new FormData(e.target); // pass the entire form

  try {
    console.log(await axios.post("http://127.0.0.1:5000/reactTest", formData));
  } catch (err) {
    console.warn(err.toJSON());
  }
};

return (
  <form onSubmit={handleSubmit}>
    <input
      type="file"
      name="file"
      onChange={(e) => setHasFiles(e.target.files.length > 0)}
    />
    <button type="submit" disabled={!hasFiles}>
      Submit
    </button>
  </form>
);

Note the file input's name is now "file" to match the field you want in FormData.

CodePudding user response:

To get the files of an input. You need to use (note you need to specify the input index):

let file = e.target[0].files 

If you want get a dict instead of imutable dict, use 'to_dict()'

request.files['file'].to_dict()

CodePudding user response:

You need to specify Content-Type: multipart/form-data header for the request to be recognized as containing file:

let handleSubmit = async (e) => {
    e.preventDefault()
    let file = e.target.files[0];
    const formData = new FormData()

    formData.append("file", file)

    axios
        .post("http://127.0.0.1:5000/reactTest", formData, {
        headers: {
            'Content-Type': 'multipart/form-data'
        })
        .then((res) => console.log(res))
        .catch((err) => console.warn(err))

... 
  • Related