JQuery Upload to Public S3 Bucket gives ------ WebKitFormBoundary

I have a webpage that gets the public byte name S3 and a unique file name to download. I am doing the download directly from javascript using jQuery. The file loads, but multi-page information is added to the file, which corrupts it.

I tried various ajax jQuery options, such as creating imageType 'image / jpeg' and trying to use PUSH instead of PUT. I even tried manually adding files to the new FormData () object manually, as you can see below.

I don’t understand how I can write a simple CURL command that works without problems, but I can’t get the HTML form submitted using jQuery to work. I feel like with jQuery it is being thrown and not assembled correctly on the side of the S3 bucket.

HTML

<form id="upload-image-form" className="clearfix" method="PUT" enctype="multipart/form-data">
<input id="product-images-add-btn" name="product-images-add-btn" type="file" onChange={this.startImageUpload} />
</form>

Javascript

$("#upload-image-form").submit(function(e)
{
    e.preventDefault();

    var formURL = $(this).attr('action');
    //var formData = new FormData($("#product-images-add-btn")[0]);  
    var formData = new FormData();
    formData.append("file", $("#product-images-add-btn")[0].files[0]);          

    $.ajax({
        url:         formURL,
        type:        "PUT",
        data:        formData,
        crossDomain: true,
        contentType: false,
        processData: false,
        success:     function(data, textStatus, jqXHR)
        {
            console.log('Successful image upload!');
            //tempThis.finishImageS3Upload();
        },
        error: function(jqXHR, textStatus, errorThrown)
        {
            console.error("Image upload error.");
        }
    });
    return false;
});



startImageUpload: function(){
    var input = $("#product-images-add-btn");
    var files = input[0].files;
    var fileTypes = [".gif",".jpg", ".png"];

    console.log("--- DEBUG. Number of files: "+files.length);

    var tempThis = this;

    if(files.length > 0)
    {
        var ext = input.val().match(/\.([^\.]+)$/)[0];

        if(fileTypes.indexOf(ext) > -1)
        {
            var file = files[0];
            var assetData = {
                "filename":    file.name,
                "filesize":    file.size,
                "type":        "IMAGE",
                "format":      file.type
            };


            $.ajax({
                url: "/getImageUploadS3Info",
                cache: false,
                contentType: 'application/json',
                crossDomain: true,
                data: assetData,
                success: function(s3Info){
                    s3Info.filename = file.name;
                    tempThis.uploadImageS3(s3Info);
                },
                error: function(a, x, e){
                    console.error("getS3InfoForUpload() ajax error.");
                }
            });

        }
        else
            console.warn("--- DEBUG. File extension "+ext+" not allowed.");
    }
    else
        console.log("--- DEBUG. No files to upload.");
}


uploadImageS3: function(s3Info){
    if(s3Info.hasOwnProperty("assetId"))
    {        
        $("#upload-image-form").attr('action', s3Info.httpUrl)
            .data('assetId', s3Info.assetId);

        console.log("--- DEBUG: submitting form.");
        $("#upload-image-form").submit();
    }
    else
        console.warn("--- ERROR: the response for getImageUploadS3Info wasn't correct.");

}

S3 Files

------WebKitFormBoundaryluTBbSMgcV0BEJcC
Content-Disposition: form-data; name="file"; filename="NewGrass.jpg"
Content-Type: image/jpeg

<image byte info stuff>

enter image description here

+4
source share
1 answer

After testing in Firefox (latest), Chrome (newest) and IE10, IE11 and Edge, this solution really works like a charm! There is no need to use additional jquery ajax functions. Browsers (namely IE) really picked up the XMLHttpRequest object. This will work for S3, but I'm still working on a solution using the jQuery $ .ajax () method to gain 100% compatibility with multiple browsers (but we don’t support IE9, so we don’t require our end)

function sendToServer (imgFile) {
    var dateTime = new Date().getTime(),//used for file name
        url = '//bucketUrl?fileName=image' + dateTime + '.png',
        xhr = new XMLHttpRequest(),
        fd = new FormData(),
        fileBlob = dataURItoBlob(img);

    fd.append('file', fileBlob);

    xhr.open('POST', url, true);

    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
            // Every thing ok, file uploaded
            console.log(xhr.responseText); // handle response.
        }
    };

    xhr.send(fd);
}

function dataURItoBlob(dataURI) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString,
        byteStringLength,
        mimeString,
        ia,
        i = 0;

    if (dataURI.split(',')[0].indexOf('base64') >= 0) {
        byteString = atob(dataURI.split(',')[1]);
    }
    else {
        byteString = unescape(dataURI.split(',')[1]);
    }

    byteStringLength = byteString.length

    // separate out the mime component
    mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    ia = new Uint8Array(byteStringLength);

    for(; i < byteStringLength; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    return new Blob([ia], {
        type: mimeString
    });
}

It looks like you forgot to encode in blob before sending. That could be all you need. Take this decodeURItoBlob function and see if this logic works with your jQuery ajax ... otherwise you can use javascript xhr to send.

0
source

All Articles