web-dev-qa-db-fra.com

Comment envoyer des images au nœud js avec Axios?

Existe-t-il un moyen d'envoyer un tableau d'images (ou une seule image) au nœud en utilisant axios?

le code axios que j'utilise (j'utilise react js sur le 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')
  }); 

Les recherches que j'ai faites suggèrent qu'il n'y a peut-être pas de moyen pris en charge pour envoyer des fichiers d'images au nœud en utilisant axios, mais cela me semble étrange. Y a-t-il un moyen?

15
J. Bones

Voici comment j'ai réussi à faire fonctionner cela correctement. J'ai dû utiliser un objet appelé FormData. J'ai utilisé l'importation:

import FormData from 'form-data'

Bien sûr, avant cette importation, j'ai dû exécuter l'installation npm pour cela:

npm install --save form-data

Une fois que j'ai fait tout cela, voici comment je l'ai utilisé dans mon 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
  });
};}

Les pièces importantes à noter ici sont:

  1. J'ai inclus des en-têtes en tant qu'objet de configuration après que l'objet de données est passé dans l'appel axios.post. Le type de contenu que vous incluez ici est la clé. Vous soumettez un type de contenu multipart/form-data.
  2. Dans cet en-tête de type de contenu, j'ai également ajouté une limite, qui est dérivée de l'objet de données que vous avez créé précédemment.
  3. Le "fichier" utilisé ici n'est que l'objet fichier que j'ai transmis à mon action. C'est juste le nom que j'ai utilisé pour mon objet, vous pouvez utiliser tout ce que vous voulez ici.

J'espère que cela aide, cela a résolu tous les problèmes que j'ai rencontrés en essayant de soumettre une image à un backend (dans mon cas, un service de repos - via un appel post).

14
Cmontalvo80

Oui, vous devrez définir le type de contenu dans votre demande axios:

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

imageFile est un fichier HTML5 ( https://developer.mozilla.org/en/docs/Web/API/File ) qui devrait être une image dans votre cas.

11
Yangshun Tay

Voici comment je l'ai implémenté:

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

Sur le serveur node js, assurez-vous d'utiliser un middleware qui gère les requêtes en plusieurs parties. J'ai utilisé multer .

Voici mes résultats sur le point final:

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

Je dirais qu'au lieu de le faire manuellement, vous pouvez utiliser une bibliothèque appelée react-dropzone pour cela. Donc, fondamentalement, ce que vous devez faire est: -

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>
          );
  }
}

Vous pouvez vérifier ici pour git repo. J'ai implémenté cela dans Django mais je ne pense pas que le backend devrait être un problème, vous pouvez utiliser le nœud

2
Harkirat Saluja

Avec HTML5, vous pouvez utiliser FormData() pour construire un ensemble de paires clé/valeur représentant les champs du formulaire et leurs valeurs que vous souhaitez envoyer. Dans la plupart des cas, comme dans le cas d'un utilisateur soumettant un formulaire, la méthode à utiliser est FormData.set() qui peut être manipulée sous ses 2 formes:

Il existe deux versions de cette méthode: une version à deux et une version à trois paramètres:

formData.set (nom, valeur);

formData.set (nom, valeur, nom de fichier);

Une fois que vous avez construit votre objet de données, n'oubliez pas de spécifier l'en-tête de type de contenu en plusieurs parties pour votre requête HTTP POST afin que vous puissiez envoyer le fichier à votre serveur.

Voici un résumé de ce que j'ai dit:

onFormSubmit(event){
    let formData = new FormData() // instantiate it
    // suppose you have your file ready
    formData.set('file', yourFile)
    // add some data you collected from the input fields
    formData.set('data1', dataInputField1) // suppose you got dataInputField1 from your HTML5 form input
    axios.post('/api/art', formData,
      headers: {
       'content-type': 'multipart/form-data' // do not forget this 
      })
  })
1
Begueradj