jQuery上传到公共S3 Bucket提供------ WebKitFormBoundary

时间:2015-06-04 21:49:51

标签: jquery amazon-s3

我有一个网页,可以获取公共S3存储桶名称和用于上传的唯一文件名。我正在使用jQuery从javascript进行上传。文件上传,但多部分信息被添加到破坏它的文件。

我尝试了不同的jQuery ajax参数,例如制作contentType' image / jpeg'并尝试使用PUSH而不是PUT。我甚至尝试手动将文件手动添加到新的FormData()对象,如下所示。

我不明白如何编写一个简单的CURL命令,它没有任何问题,但我无法使用jQuery提交HTML表单。我觉得和jQuery一样,它被扔掉了,而且没有在S3斗端正确放在一起。

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档案

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

<image byte info stuff>

enter image description here

1 个答案:

答案 0 :(得分:0)

在Firefox(最新),Chrome(最新)和IE10,IE11和Edge测试后,这个解决方案确实像魅力一样!这里不需要jquery的ajax方法的开销。浏览器(即IE)确实选择了XMLHttpRequest对象。这将完成S3的工作,但我仍在使用jQuery的$ .ajax()方法来解决100%的跨浏览器兼容性问题(但我们不支持IE9,所以我们不需要):

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

在发送之前,您似乎忘记编码为blob。这可能就是你所需要的。抓住decodeURItoBlob函数并查看该逻辑是否适用于您的jquery ajax方法...否则,您可以使用javascript xhr发送它。