2010-12-08 38 views
8

J'ai un fichier jpg encodé en base64 en javascript que je souhaite publier sur un serveur qui attend des données multipart/form.Conversion d'image base64 en multipart/form-data et envoi avec jQuery

Plus précisément, à l'API de suivi pivot, qui a un exemple curl appeler comme ceci:

curl -H "X-TrackerToken: TOKEN" -X POST -F [email protected]/path/to/file \ 
http://www.pivotaltracker.com/services/v3/projects/PROJECT_ID/stories/STORY_ID/attachments 

Je XML de base appelle seulement à leur API fonctionne bien, en utilisant .ajax comme ceci:

$.ajax({ 
    url: 'http://www.pivotaltracker.com/services/v3/projects/158325/stories', 
    type: 'POST', 
    contentType: 'application/xml', 
    dataType: 'xml', 
    beforeSend: function(xhr) { 
    xhr.setRequestHeader("X-TrackerToken", "<KEY>") 
    }, 
    data: '<story><story_type>feature</story_type><name>Fire torpedoes</name></story>', 
    success: function() { alert('PUT completed'); } 
}); 

mais je suis perplexe sur la façon de prendre mon jpg encodé en base64 et l'envoyer comme si j'avais téléchargé un fichier dans un formulaire.

Des idées?

Répondre

4

Assez simple. Je l'ai essayé avec JQuery comme vous l'avez fait, mais je n'ai pas pu l'accomplir. Je suis donc allé de l'avant et construit ma propre implémentation XHR qui enverra un corps multi-parties personnalisé au serveur.

1) votre XHR Initialize 2) Construire le corps multipart ensemble 3) Envoyez-

var xhr = new XMLHttpRequest(); 
... 
xhr.open("POST", url, true); 

var boundary = '------multipartformboundary' + (new Date).getTime(), 
dashdash = '--', 
crlf = '\r\n', 

C'est là que la magie se produit. Vous construisez votre propre « corps » pour la transmission et mettre l'image données comme une variable normale avec nom dans le corps:

content = dashdash+boundary+crlf+'Content-Disposition: form-data; name="NAMEOFVARIABLEINPHP";"'+crlf+crlf+VARIABLEWITHBASE64IMAGE+crlf+dashdash+boundary+dashdash+crlf; 

Ensuite, il suffit envoyer de:

xhr.setRequestHeader("Content-type", "multipart/form-data; boundary="+boundary); 
xhr.setRequestHeader("Content-length", content.length); 
xhr.setRequestHeader("Connection", "close"); 
// execute 
xhr.send(content); 

Si vous utilisez PHP, vous avez une nouvelle variable dans votre $ _POST contenant la chaîne codée base64. Cela empêchera le navigateur de casser la chaîne en 72 caractères/ligne et de supprimer les + et autres caractères spéciaux.

Espérons que ça aide.

0

Tout ce que vous devez faire est de convertir les données de base64 à blob et l'envoyer par FormData

function b64toBlob(b64Data, contentType, sliceSize) { 
      contentType = contentType || ''; 
      sliceSize = sliceSize || 512; 

      var byteCharacters = atob(b64Data); 
      var byteArrays = []; 

      for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { 
       var slice = byteCharacters.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); 
      } 

      var blob = new Blob(byteArrays, {type: contentType}); 
      return blob; 
} 


function imagetoblob(ImgId){ 
    var ImageURL = document.getElementById(ImgId).getAttribute('src'); 
    // Split the base64 string in data and contentType 
    var block = ImageURL.split(";"); 
    // Get the content type of the image 
    var contentType = block[0].split(":")[1];// In this case "image/gif" 
    // get the real base64 content of the file 
    var realData = block[1].split(",")[1];// In this case "R0lGODlhPQBEAPeoAJosM...." 

    // Convert it to a blob to upload 
    return b64toBlob(realData, contentType); 
} 

Dans vos données de formulaire

formData.append("image", imagetoblob('cropped_image'));