Преобразование изображения base64 в составные / form-данные и отправка с помощью jQuery

#javascript #jquery #api #base64

#javascript #jquery #API #base64

Вопрос:

У меня есть jpg в кодировке base64 на javascript, который я хотел бы опубликовать на сервере, ожидающем составные данные / form-data.

В частности, к API pivotal tracker, в котором есть пример вызова curl следующим образом:

 curl -H "X-TrackerToken: TOKEN" -X POST -F Filedata=@/path/to/file 
http://www.pivotaltracker.com/services/v3/projects/PROJECT_ID/stories/STORY_ID/attachments
  

У меня есть только базовые вызовы XML для их API, которые работают нормально, используя .ajax вот так:

 $.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'); }
});
  

но я в тупике относительно того, как взять мой файл jpg в кодировке base64 и отправить его так, как если бы я загрузил файл в форме.

Есть идеи?

Ответ №1:

Довольно прямолинейно. Я попробовал это с помощью jQuery, как и вы, но не смог этого выполнить. Итак, я пошел дальше и создал свою собственную реализацию XHR, которая отправит пользовательское составное тело на сервер.

1) Инициализируйте свой XHR 2) Соберите составное тело вместе 3) Отправьте его

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

var boundary = '------multipartformboundary'   (new Date).getTime(),
dashdash = '--',
crlf = 'rn',
  

Вот где происходит волшебство. Вы создаете свое собственное «тело» для передачи и помещаете данные изображения в виде обычной переменной с именем в тело:

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

Затем просто отправьте его из:

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

Если вы используете PHP, у вас в вашем $_POST появится новая переменная, содержащая строку в кодировке base64. Это предотвратит разбиение строки браузером на 72 символа на строку и удаление символов и других специальных символов.

Надеюсь, это поможет.

Ответ №2:

Все, что вам нужно сделать, это преобразовать данные base64 в большой двоичный объект и отправить его через 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);
}
  

В вашей форме данные

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