Comment envoyer AntiForgeryToken (CSRF) avec FormData via jquery ajax

Donc je veux POST fileUpload avec AntiForgeryToken via AJAX. Voici mon code:

Vue

 @using (Html.BeginForm("Upload", "RX", FormMethod.Post, new {id = "frmRXUpload", enctype = "multipart/form-data"})) { @Html.AntiForgeryToken() @Html.TextBoxFor(m => m.RXFile, new {.type = "file"}) ...rest of code here }  $(document).ready(function(){ $('#btnRXUpload').click(function () { var form = $('#frmRXUpload') if (form.valid()) { var formData = new FormData(form); formData.append('files', $('#frmRXUpload input[type="file"]')[0].files[0]); formData.append('__RequestVerificationToken', fnGetToken()); $.ajax({ type: 'POST', url: '/RX/Upload', data: formData, contentType: false, processData: false }) } }) })  

Manette

 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Upload() { //rest of code here } 

Je reçois

Le jeton anti-falsification n’a pas pu être déchiffré. Si cette application est hébergée par une batterie de serveurs Web ou un cluster

erreur via le violoniste. Une idée de comment résoudre ce problème?

J’ai trouvé la réponse:

  $(document).ready(function(){ $('#btnRXUpload').click(function () { var form = $('#frmRXUpload') if (form.valid()) { var formData = new FormData(form.get(0)); //add .get(0) formData.append('files', $('#frmRXUpload input[type="file"]')[0].files[0]); $.ajax({ type: 'POST', url: '/RX/Upload', data: formData, contentType: false, processData: false }) } }) })  

FINALEMENT TROUVÉ LA RÉPONSE:

J’ai juste besoin d’append .get(0) dans le formulaire, voici le code:

  

Vous devez append le jeton aux en-têtes de la demande, pas au formulaire. Comme ça:

  if (form.valid()) { var formData = new FormData(form); formData.append('files', $('#frmRXUpload input[type="file"]')[0].files[0]); $.ajax({ type: 'POST', url: '/RX/Upload', data: formData, contentType: 'multipart/form-data', processData: false, headers: { '__RequestVerificationToken': fnGetToken() } }) } 

En regardant comment j’ai résolu ce problème moi-même, je me souviens que l’object standard ValidateAntiForgeryTokenAtsortingbute recherche dans l’object Request.Form qui n’est pas toujours renseigné pour une demande AJAX. (Dans votre cas, le téléchargement de fichier nécessite un type de contenu multipart/form-data , alors qu’une publication de formulaire pour le jeton CSRF nécessite application/x-www-form-urlencoded . Vous définissez contentType=false , mais les deux opérations nécessitent un contenu conflictuel types, qui peuvent faire partie de votre problème). Ainsi, afin de valider le jeton sur le serveur, vous devrez écrire un atsortingbut personnalisé pour votre méthode d’action qui vérifie le jeton dans l’en-tête de la requête:

 public sealed class ValidateJsonAntiForgeryTokenAtsortingbute : FilterAtsortingbute, IAuthorizationFilter { public void OnAuthorization(AuthorizationContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } var httpContext = filterContext.HttpContext; var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName]; AntiForgery.Validate(cookie != null ? cookie.Value : null, httpContext.Request.Headers["__RequestVerificationToken"]); } } 

Plus d’infos (un peu démodé maintenant) ici .