How do you send images to node js with Axios?

2019-02-12 14:55发布

问题:

Is there a way to send an array of images (or a single image) to node using axios?

the axios code I'm using(I'm using react js on the front end):


onFormSubmit(event){
    event.preventDefault();
    let payload = this.state;
    console.log("in onFormSubmit!!! with state: ", this.state, "and payload: ", payload);
    axios.post('/api/art', payload)
    .then(function(response){
    console.log('saved successfully')
  }); 

The research I've done suggests that perhaps there isn't a supported way to send image files to node using axios, but this seems strange to me. Is there a way?

回答1:

Here is the way I got this to work properly. I had to make use of an object called FormData. I used the import:

import FormData from 'form-data'

Of course before this import I had to run the npm install for it:

npm install --save form-data

Once I did all that, here is how I used it within my action:

let data = new FormData();
data.append('file', file, file.fileName);

return (dispatch) => {
axios.post(URL, data, {
  headers: {
    'accept': 'application/json',
    'Accept-Language': 'en-US,en;q=0.8',
    'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
  }
})
  .then((response) => {
    //handle success
  }).catch((error) => {
    //handle error
  });
};}

The important pieces to note here are:

  1. I included some headers as a configuration object after the data object passed into the axios.post call. The content type you're including here is the key. You're submitting a multipart/form-data content type.
  2. Within that Content type header, I also added a boundary, which is derived from the data object you created earlier.
  3. The 'file' used here is just the file object I passed into my action. It's just the name I used for my object, you can use anything you want here.

Hope this helps, this cleared up all of the issues I had with trying to submit an image to a backend (in my case a rest service - through a post call).



回答2:

Yes you will have to set the content type in your axios request:

axios.put(url, imageFile, {
  headers: {
    'Content-Type': imageFile.type
  }
});

where imageFile is an HTML5 file (https://developer.mozilla.org/en/docs/Web/API/File) which should be an image in your case.



回答3:

Here is how I implemented it:

onFormSubmit(event){
    var form = new FormData();
    files.forEach(file => {
        form.append(file.name, file);
    });
    form.append('foo', 'bar');
    axios.post('/api/art', form)    
}); 

On node js server make sure to use some middle-ware which handles multipart requests. I used multer.

Here are my results on the endpoint:

req.body - { foo: 'bar' }
req.files - { 
    'r1.jpg': { 
      fieldname: 'r1.jpg',
      originalname: 'r1.jpg',
      name: 'e2f4b9874fd7d6115b9f7440b9ead3a0.jpg',
      encoding: '7bit',
      mimetype: 'image/jpeg',
      path: '/tmp/e2f4b9874fd7d6115b9f7440b9ead3a0.jpg',
      extension: 'jpg',
      size: 45641,
      truncated: false,
      buffer: null 
    }, ...
}


回答4:

I would say instead of doing this manually you can use a library called react-dropzone for this . So basically what you need to do is :-

import React,{Component} from 'react';
import Dropzone from 'react-dropzone';
import request from 'superagent';

class DropZone extends Component{

  onDrop(files){
    var file = new FormData();
    file.append('name',files[0])
    var req=request
              .post('http://localhost:8000/api/v0/image/')
              .send(file);
    req.end(function(err,response){
        console.log("upload done!!!!!");
    });
  }

  render(){
    return(
      <div>
        <Dropzone onDrop={this.onDrop}>
          <div>Try dropping some files here, or click to select files to upload.</div>
        </Dropzone>
      </div>
          );
  }
}

You can check here for git repo. I have implemented this in django but i dont think backend should be a problem, you can use node