it-swarm.com.ru

Загрузите изображение base64 с помощью Ajax

Мой клиент предлагает пользователю выбрать изображение, обрезать и изменить его размер, а затем отобразить его (в элементе DOM <img>).
Если изображение в порядке, пользователь может загрузить его на сервер, чтобы его можно было сохранить.

Я хотел бы сделать загрузку благодаря запросу Ajax.

Я нашел тонны примеров в интернете для загрузки исходного изображения полученного с клиентского ПК. Например:

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

Это работает правильно, если я решу загрузить изображение, полученное через форму ввода.

В моем случае я хочу загрузить измененное изображение (сохраненное в элементе <img>) вместо исходного.
Это изображение хранится как изображение base64 (Для информации: я использовал библиотеку croppie.js для генерации изображения).

Я не знаю, как загрузить эту картинку с помощью Ajax.

Я пытался загрузить его как обычный параметр, но на стороне сервера img - пустая строка:

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.

Моя проблема в том, что на сервере была пустая строка при получении параметра "img". Я подозреваю, что изображение может быть слишком большим, чтобы быть переданным на сервер или другие проблемы, которые я не понимаю ....

Поэтому мне интересно, каков правильный способ отправки образа base64 на сервер с помощью Ajax-запросаБЕЗс использованием формы.

Спасибо за вашу помощь.

ПРАВКА

Кажется, это проблема размера параметра xmlHTTP POST. Я попытался уменьшить количество символов в строковом представлении изображения, и теперь сервер может получить его.

EDIT2

значение post_max_size равно 8M в файле php.ini, тогда как размер изображения составляет всего 24K. Так что проблема не в этом.
Я использую PHP с фреймворком Symfony2.
Возможно ограничение от Symfony2.

16
Nitseg

Наконец я решил преобразовать изображение base64 в BLOB-объект, чтобы его можно было отправить с помощью Ajax-запроса с объектом formData следующим образом .. Это экономит полосу загрузки (base64 занимает на 33% больше битов, чем его двоичный эквивалент), и я не смог не найти причину отсутствия передачи параметра base64 (из-за ограничения размера где-то наверняка).

Функция base64ToBlob основана на это ответ на другой вопрос .

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});
}

Мой код 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!');
        });

В Symfony2 я могу получить изображение благодаря:

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

Ответ Ницега работает хорошо. Кроме того, я хотел добавить следующие строки, если вы должны использовать токен auth в вашем вызове ajax. Опять же, посмотрите на ответ Ницега для более подробной информации в первую очередь.

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!
}); 
1
omt66