web-dev-qa-db-fra.com

Téléchargement d'une image avec redux-form

J'ai un formulaire redux react.js qui fonctionne et publie des données sur mon API, mais je dois également autoriser le demandeur à télécharger une image avec le formulaire, idéalement avec un aperçu. J'ai eu un peu de mal et suis arrivé à dropzone.js mais je n'arrive pas à récupérer mon formulaire pour réellement POST les données d'image en arrière.

render () {
  const FILE_FIELD_NAME = 'files';

    const renderDropzoneInput = (field) => {
      const files = field.input.value;
      return (
        <div>
          <Dropzone
            name={field.name}
            onDrop={( filesToUpload, e ) => field.input.onChange(filesToUpload)}
          >
            <div>Try dropping some files here, or click to select files to upload.</div>
          </Dropzone>
          {field.meta.touched &&
            field.meta.error &&
            <span className="error">{field.meta.error}</span>}
          {files && Array.isArray(files) && (
            <ul>
              { files.map((file, i) => <li key={i}>{file.name}<img src={file.preview}/></li>) }
            </ul>
          )}
        </div>
      );
    }

    return (
        <form onSubmit={this.props.handleSubmit(this.onSubmit)}>
          <div className="form-group">
            <Field name="files" component={renderDropzoneInput} />
          </div>
          <button type="submit" className="btn btn-default">Submit</button>
        </form>
    );
}

La variable files est renvoyée POST à ​​l'API, ce qui est génial mais elle contient les éléments suivants:

[preview=blob:http://localhost:3000/bed3762e-a4de-4d19-8039-97cebaaca5c1]

Quelqu'un peut-il suggérer comment j'obtiens les données binaires réelles dans cette variable, s'il vous plaît?

Le code complet est disponible ici https://github.com/rushughes/dsloracle/blob/master/client/src/components/LandCreate/index.js

11
RusHughes

J'ai récemment rencontré un problème similaire et l'ai résolu en utilisant l'API FileReader pour convertir l'URL de l'objet blob en Base64 (peut également être converti en chaîne binaire).

Ensuite, vous envoyez la base64 ou la chaîne binaire au serveur.

Mon exemple de code:

onDrop(acceptedFiles: any): any {

    let images: any = this.state.Images;

    acceptedFiles.forEach((file: any) => {

        const reader: FileReader = new FileReader();
        reader.onload = () => {
            const fileAsBase64: any = reader.result.substr(reader.result.indexOf(",") + 1);
            images.Push(fileAsBase64);
        };

        reader.onabort = () => console.log("file reading was aborted");
        reader.onerror = () => console.log("file reading has failed");

        reader.readAsDataURL(file);
    });

    this.setState(prevState => ({   
         Images: images,
    }));
}

Si vous souhaitez envoyer une chaîne binaire au lieu de base64, changez reader.readAsDataURL(file); en reader.readAsBinaryString(file);

et cette ligne: const fileAsBase64: any = reader.result.substr(reader.result.indexOf(",") + 1); peut être simplifiée en const file: any = reader.result;

3
Liam Kenneth

Voici les étapes pour file-upload fonctionnalité: (Comment gérer les données d'image dans votre API)

  • Ajoutez vos valeurs de formulaire redux à l'instance FormData .

    let formData = new FormData();
    formData.append('myFile', files[0]);
    
  • Envoyer multipart/form-data demande du Client à votre API avec axios ou fetch bibliothèque:

  • Recevez ça multipart/form-data demande dans votre API, traitez-la avec multer puis écrivez le fichier dans le disk storage ou memory storage comme suit:

    $ npm install --save multer
    
    const multer  = require('multer')
    
    const storage = multer.diskStorage({
      destination: function (req, file, cb) {
      cb(null, '/tmp/my-uploads')
     },
      filename: function (req, file, cb) {
      cb(null, file.fieldname + '-' + Date.now())
     }
    })
    
    const upload = multer({ storage: storage })
    
    const app = express()
    
    app.post('/upload', upload.single('myFile'), (req, res, next) => {
      // req.file is the `myFile` file
      // req.body will hold the text fields, if there were any
     })
    
  • (Facultatif) Servir des fichiers directement à partir de votre API avec Express Serve-Static

2
gokcand
1
Muhammad Hannan

Gérer le téléchargement d'images avec Node serveur

Essayez d'attraper un fichier dans la fonction de point de terminaison du serveur en utilisant formidable

app.post('/upload', function (req, res) { // express endpoint 
    var form = new formidable.IncomingForm();

    form.parse(req, function(err, fields, files) { // "req" is server request object
       fs.rename(files.file.path, "/tmp/" + files.file.name); // move file to desired location
    });

    // handle rest of text fields from req.body if there are any
});

Ceci est un exemple de nœud express, mais vous pouvez utiliser le nœud http comme dans un formidable exemple

0
zarcode