2015-06-04 29 views
4

我有一個網頁,獲取公共S3存儲桶的名稱和唯一的文件名用於上傳。我正在使用jQuery從javascript進行上傳。文件上傳,但多部分信息預先添加到損壞它的文件。jQuery上傳到公共S3桶提供------ WebKitFormBoundary

我已經嘗試了不同的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

+0

我面臨着這個完全相同的問題,你能解決它嗎? – dev123

+0

不可以。我們最終回到將文件發送到我們的後端Java並將其上傳到S3 – Hososugi

回答

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發送它。

相關問題