weixin_33716941 2016-01-14 00:47 采纳率: 0%
浏览 368

使用Ajax上传base64图像

My client is offering the user to pick a picture, crop and resize it and then display it (in a <img> DOM element).
If the picture is fine, the user can upload it to the server so it can be saved.

I would like to do the upload thanks to an Ajax request.

I found tons of examples on the internet to upload the original image retrieved from the client PC. For instance:

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

This works properly if I decide to upload the picture retrieved through the form input.

In my case I want to upload the modified picture (saved in a <img> element) instead of the original one.
This picture is stored as a base64 picture (For information: I used the croppie.js library to generate the image).

I don't know how to upload this picture with Ajax.

I tried to upload it as a regular parameter but on the server side the img is an empty string:

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.

My problem being the server having an empty string when retrieving the "img" parameter. I suspect the image is maybe too big to be passed to the server or some other issues that I don't understand... .

So I'm wondering what is the proper way to send a base64 image to the server using an Ajax request WITHOUT using a form.

Thanks for your help.

EDIT

Seems to be an xmlHTTP POST parameter size issue. I tried to reduce the number of characters of the string representation of the image and the server is now able to retrieve it.

EDIT2

post_max_size is set to 8M in the php.ini file wheras the picture size is only 24K. So the problem is not there.
I'm using PHP with the Symfony2 framework.
Maybe a limitation from Symfony2.

  • 写回答

2条回答 默认 最新

  • bug^君 2016-01-14 12:27
    关注

    I finally decided to convert the base64 image to a Blob so it can be sent via an Ajax request with the formData object as follows. It saves upload bandwidth (base64 takes 33% more bits than its binary equivalent) and I couldn't find the reason for no transmission of base64 parameter (due to size limitation somewhere for sure).

    The base64ToBlob function is based on this answer to another 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});
    }
    

    My JS code:

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

    In Symfony2 I can retrieve the image thanks to:

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

报告相同问题?