99

When I curl something, it works fine:

curl -L -i -H 'x-device-id: abc' -F "url=http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"  http://example.com/upload

How do I get this to work right with axios? I'm using react if that matters:

uploadURL (url) {
  return axios.post({
    url: 'http://example.com/upload',
    data: {
      url: url
    },
    headers: {
      'x-device-id': 'stuff',
      'Content-Type': 'multipart/form-data'
    }
  })
  .then((response) => response.data)
}

This doesn't work for some reason.

Shamoon
  • 38,429
  • 77
  • 269
  • 518
  • What is the exact error here? Do you get a specific response code from the server? Also posting fiddler event logs could help. – hazardous Feb 02 '17 at 11:19

3 Answers3

165

Here's how I do file upload in react using axios

import React from 'react'
import axios, { post } from 'axios';

class SimpleReactFileUpload extends React.Component {

  constructor(props) {
    super(props);
    this.state ={
      file:null
    }
    this.onFormSubmit = this.onFormSubmit.bind(this)
    this.onChange = this.onChange.bind(this)
    this.fileUpload = this.fileUpload.bind(this)
  }

  onFormSubmit(e){
    e.preventDefault() // Stop form submit
    this.fileUpload(this.state.file).then((response)=>{
      console.log(response.data);
    })
  }

  onChange(e) {
    this.setState({file:e.target.files[0]})
  }

  fileUpload(file){
    const url = 'http://example.com/file-upload';
    const formData = new FormData();
    formData.append('file',file)
    const config = {
        headers: {
            'content-type': 'multipart/form-data'
        }
    }
    return  post(url, formData,config)
  }

  render() {
    return (
      <form onSubmit={this.onFormSubmit}>
        <h1>File Upload</h1>
        <input type="file" onChange={this.onChange} />
        <button type="submit">Upload</button>
      </form>
   )
  }
}



export default SimpleReactFileUpload

Source

Busti
  • 5,294
  • 2
  • 19
  • 31
Ashik Nesin
  • 1,768
  • 1
  • 8
  • 7
  • 4
    How to send multiple files in this case? – Dani Vijay Sep 06 '18 at 12:54
  • 4
    Why do you need to specify `multipart/form-data` ? It should be already built in in `FormData `. Source(https://github.com/axios/axios/issues/318#issuecomment-218948420) – Artem Bernatskyi Jan 24 '19 at 18:39
  • You can pass the form element as an argument when instantiating a `FormData` object, which is really useful as it populates the object with the form's keys and their values. – Darragh Enright Sep 27 '20 at 23:56
15

If you are sending alphanumeric data try changing

'Content-Type': 'multipart/form-data'

to

'Content-Type': 'application/x-www-form-urlencoded'

If you are sending non-alphanumeric data try to remove 'Content-Type' at all.

If it still does not work, consider trying request-promise (at least to test whether it is really axios problem or not)

Shota
  • 6,290
  • 7
  • 33
  • 60
3

ok. I tried the above two ways but it didnt work for me. After trial and error i came to know that actually the file was not getting saved in 'this.state.file' variable.

fileUpload = (e) => {
    let data = e.target.files
    if(e.target.files[0]!=null){
        this.props.UserAction.fileUpload(data[0], this.fallBackMethod)
    }
}

here fileUpload is a different js file which accepts two params like this

export default (file , callback) => {
const formData = new FormData();
formData.append('fileUpload', file);

return dispatch => {
    axios.put(BaseUrl.RestUrl + "ur/url", formData)
        .then(response => {
            callback(response.data);
        }).catch(error => {
         console.log("*****  "+error)
    });
}

}

don't forget to bind method in the constructor. Let me know if you need more help in this.