Télécharger l'image base64 avec Ajax

Mon client offre à l'utilisateur de choisir une image, de la récolter et de la redimensionner, puis de l'afficher (dans un <img> élément DOM).
Si la photo est bien, l'utilisateur peut la télécharger sur le serveur afin qu'elle puisse être enregistrée.

J'aimerais faire le téléchargement grâce à une requête Ajax.

J'ai trouvé beaucoup d'exemples sur Internet pour télécharger l'image originale récupérée à partir du PC client. Par exemple:

 $( '#my-form' ) .submit( function( e ) { $.ajax( { url: 'http://host.com/action/', type: 'POST', data: new FormData( this ), processData: false, contentType: false } ); e.preventDefault(); } ); 

Cela fonctionne correctement si je décide de télécharger l'image récupérée via l'entrée de formulaire.

Dans mon cas, je souhaite télécharger l'image modifiée (enregistrée dans un élément <img> ) au lieu de l'original.
Cette image est stockée sous forme d'image base64 (Pour plus d'informations: j'ai utilisé la bibliothèque croppie.js pour générer l'image).

Je ne sais pas comment télécharger cette image avec Ajax.

J'ai essayé de le télécharger comme un paramètre régulier mais du côté du serveur, l'img est une chaîne vide:

 var url = 'http://host.com/action/'; var data = {}; data.img = $('img#generated-image').attr('src'); $.ajax({url: url, type: "POST", data: data}) .done(function(e){ // Do something }); // RESULTS in a empty data.img on the server side. 

Mon problème étant le serveur ayant une chaîne vide lors de la récupération du paramètre "img". Je soupçonne que l'image est peut-être trop grande pour être transmise au serveur ou d'autres problèmes que je ne comprend pas …

Je me demande donc quelle est la manière appropriée d'envoyer une image base64 au serveur en utilisant une requête Ajax SANS utiliser un formulaire.

Merci de votre aide.

MODIFIER

Semble être un problème de taille de paramètre POST xmlHTTP. J'ai essayé de réduire le nombre de caractères de la représentation de chaîne de l'image et le serveur peut maintenant la récupérer.

EDIT2

Post_max_size est réglé sur 8M dans le fichier php.ini lorsque la taille de l'image est de seulement 24K. Le problème n'est donc pas là.
J'utilise PHP avec le framework Symfony2.
Peut-être une limitation de Symfony2.

J'ai finalement décidé de convertir l'image base64 en une Blob afin qu'elle puisse être envoyée via une requête Ajax avec l'objet formData comme suit. Il économise la bande passante de téléchargement (base64 prend 33% de plus de bits que son équivalent binaire) et je n'ai pas trouvé le motif de la transmission du paramètre base64 (en raison de la limitation de taille quelque part sûr).

La fonction base64ToBlob est basée sur cette réponse à une autre question .

 function base64ToBlob(base64, mime) { mime = mime || ''; var sliceSize = 1024; var byteChars = window.atob(base64); var byteArrays = []; for (var offset = 0, len = byteChars.length; offset < len; offset += sliceSize) { var slice = byteChars.slice(offset, offset + sliceSize); var byteNumbers = new Array(slice.length); for (var i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } var byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } return new Blob(byteArrays, {type: mime}); } 

Mon code JS:

 var url = "url/action"; var image = $('#image-id').attr('src'); var base64ImageContent = image.replace(/^data:image\/(png|jpg);base64,/, ""); var blob = base64ToBlob(base64ImageContent, 'image/png'); var formData = new FormData(); formData.append('picture', blob); $.ajax({ url: url, type: "POST", cache: false, contentType: false, processData: false, data: formData}) .done(function(e){ alert('done!'); }); 

Dans Symfony2, je peux récupérer l'image grâce à:

 $picture = $request->files->get('picture'); 

La réponse de Nitseg fonctionne bien. De plus, je voulais ajouter les lignes suivantes si vous devez utiliser le jeton auth dans votre appel ajax. Encore une fois, regardez la réponse de Nitseg pour plus de détails d'abord.

 var formData = new FormData(); var token = "<YOUR-TOKEN-HERE>"; formData.append("uploadfile", mediaBlob); jQuery.ajax({ url: url, type: "POST", cache: false, contentType: false, processData: false, data: formData, beforeSend: function (xhr){ xhr.setRequestHeader("Authorization", "Bearer " + token); } }) .done((e) => { // It is done. }) .fail((e) => { // Report that there is a problem! });