2017-09-05 9 views
1

Donc, je construis une petite application pour apprendre à utiliser express.js. J'ai un formulaire très simple, en soumettant un champ de texte et un fichier simultanément. Ceci est soumis via FormData, donc j'utilise multer sur le backend pour traiter la requête. Ce que je voudrais faire est d'effectuer une validation sur l'entrée de texte du formulaire AVANT en prenant n'importe quelle action concernant le fichier (c'est-à-dire enregistrer seulement si la validation réussit, sinon envoyer une sorte de message d'erreur). Je l'habitude de le faire de cette façonNouvelle syntaxe express-validator: valider le formulaire traité par multer

<form id="form" method='POST' enctype='multipart/form-data'> 
     <input type='file' id='file-upload' name='file-upload' /> 
     <input type='text' id='text-upload' name='text-upload' /> 
     <input type='submit' /> 
</form> 

fin Retour: router.js

//somewhere in the router file 
import {importedController} from './controllers/importedController'; 
/* some other routes */ 
router.post('/upload', importedController.processfunction); 

importedController.js

exports.processfunction = (req, res, next) => { 
var getFields = multer().any(); 
getFields(req, res, err => { 
if (err) {return next(err);} 
req.checkBody('text-upload','must not be empty!').notEmpty(); 
//do the validation from here 
var errors = req.validationErrors(); 
if (errors) { 
    //some logic 
} else { 
    //some other stuff 
    //in both, i can access req.body and req.file to do whatever i want 
} 
}); 
} 

Je remarquai cependant qu'il semble être a new syntax for express validator, donc j'ai essayé de suivre cette syntaxe et de faire:

router.js

router.post('/upload', [ body('text-input', 'must be not empty').not().isEmpty()], importedController.processfunction); 

mais alors dans mes importedController.js, le travail ne marche pas de validation en dehors de la fonction Multer getFields() que je définissais (semble logique puisque la demande n'a pas été traitée encore). Pourtant, si je tente de l'inclure dans la fonction multer:

importedController.js

exports.processfunction = (req, res, next) => { 
var getFields = multer().any(); 
getFields(req, res, err => { 
    if (err) {return next(err);} 
    errors = validationResult(req); 
    if (!errors.isEmpty()) { 
    //actually always yields and error... 
    } else { //stuff} 
}); 
} 

Ensuite, il retourne toujours une erreur, bien que l'entrée sur le terrain est correct. C'est comme si la validation était effectuée sur le req 'non traité', où req.body est vide. Bien que le code fonctionne maintenant, il n'y a pas de hâte, je voudrais suivre la nouvelle syntaxe pour les projets ultérieurs. Toute aide grandement appréciée!

EDIT: Une solution que je trouve grâce à @ réponse de gustavohenke ci-dessous

réalisé que jusqu'au coeur, mon problème était lié à façon le fonctionnement du module Multer, car il semble télécharger le fichier avant qu'il traite les données du formulaire (qui doivent venir avant la validation) - au moins, le module multer ne semble pas vous donner le contrôle sur le moment où il télécharge le fichier, ce qui vous empêche d'appeler un autre middleware avant de l'enregistrer. Donc, ce que j'ai fini par faire était d'utiliser ajax côté client pour d'abord envoyer les données de formulaire seulement (en sauvegardant le fichier pour plus tard), dans un intergiciel multer().any() enchaîné avec la logique de validation de formulaire. En fonction de la réponse donnée par ce premier appel au serveur, je l'enchaîne ensuite avec un autre ajax pour enfin télécharger le fichier sur un autre itinéraire, cette fois en utilisant un multer(storage: myStorage).single('myFileInputName') pour télécharger le fichier. En y pensant, cette solution semble peut-être mieux que ce que je pensais faire au début: non seulement elle évite d'enregistrer le fichier en cas de mauvaise saisie, elle évite même d'utiliser toute la bande passante pour envoyer le fichier (ça peut être décemment lourd) si l'entrée est incorrecte.

Répondre

0

Vous avez raison lorsque vous dites que la validation a eu lieu avant le corps a été traité par multer.Dans les deux cas, les validateurs sont exécutés dès que possible; mais s'il vous plaît noter les différences suivantes:

  • Dans l'exemple que vous avez donné pour l'API héritage, vous définissez les dans les validations le rappel multer, après que le corps a été traité. Par conséquent, cela fonctionne.
  • Cependant, dans votre exemple d'API de vérification, les validateurs sont définis avant que multer ait une chance d'être exécutée, donc vous aurez toujours des erreurs - req.body est toujours vide.
+1

Merci beaucoup! C'était comme je me doutais alors :) J'ai mis à jour mon post avec une solution de contournement que j'ai trouvée, en utilisant deux routes différentes et ajax pour télécharger le formulaire en 2 parties. Ne pas avoir le représentant pour vous «publiquement» upvote encore, mais a fait de toute façon ... –

+0

Merci, pas de soucis! Continuez à utiliser express-validator et poster vos commentaires :) – gustavohenke