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
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;
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
Il existe des solutions disponibles pour React.js avec Dropzone. Veuillez vous référer à ce qui suit:
http://reactdropzone.azurewebsites.net/example/
Quel code peut être trouvé ici: https://react.rocks/example/React-Dropzone
De plus, ces solutions vous aideront également d'une manière ou d'une autre à sortir du problème:
https://github.com/react-dropzone/react-dropzone
https://medium.com/technoetics/handling-file-upload-in-reactjs-b9b95068f6b
http://blog.mauriziobonani.com/dropzone.js-react.js-and-fluxxor-integration/
https://css-tricks.com/image-upload-manipulation-react/
https://www.reddit.com/r/reactjs/comments/6k6fjr/reactdropzone_integration_with_react/
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