web-dev-qa-db-ja.com

Ajaxでbase64イメージをアップロードする

私のクライアントは、ユーザーに画像を選択し、切り抜き、サイズ変更してから表示することを提供しています(<img> DOM要素)。
画像に問題がなければ、ユーザーは画像をサーバーにアップロードして保存できます。

Ajaxリクエストのおかげでアップロードしたいと思います。

インターネット上にアップロードする多数の例を見つけました元の画像クライアントPCから取得しました。例えば:

$( '#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要求を使用して[〜#〜] without [〜#〜]を使用して。

ご協力いただきありがとうございます。

[〜#〜] edit [〜#〜]

XmlHTTP POSTパラメータサイズの問題のようです。画像の文字列表現の文字数を削減しようとしましたが、サーバーはそれを取得できるようになりました。

EDIT2

post_max_sizeはphp.iniファイルで8Mに設定されていますが、画像サイズは24Kしかありません。そのため、問題はありません。
Symfony2フレームワークでPHPを使用しています。
Symfony2の制限かもしれません。

19
Nitseg

最終的に、base64イメージをBlobに変換して、次のようにformDataオブジェクトでAjaxリクエストを介して送信できるようにすることにしました。それはアップロード帯域幅を節約します(base64はそのバイナリ同等物よりも33%多くのビットを使用します)。

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');
36
Nitseg

Nitsegの答えはうまくいきます。また、ajax呼び出しで認証トークンを使用する必要がある場合は、次の行を追加しました。繰り返しになりますが、詳細については、まずNitsegの回答をご覧ください。

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