2013-07-26 118 views
2

我想使用ajax請求將包含多個文件的zip文件從客戶端發送到服務器。 拉鍊被編碼爲Base64字符串在JavaScript和作爲後參數傳遞通過POST發送ZIP文件到Base64中的服務器

Javascript代碼:到目前爲止

@RequestMapping(value = "/X", method = RequestMethod.POST) 
    public String X(@RequestParam("file") String file, @RequestParam("fileName") String fileName, Locale locale, Model model) { 


      System.out.println(file); 

      byte[] decoded = Base64.decodeBase64(file); 

      System.out.println(decoded); 


      File folder = new File("C:\\MTT"); 
      if(!folder.exists()){ 
       folder.mkdir(); 
      } 

      File f = new File("C:\\MTT\\"+fileName); 



try { 
        FileOutputStream fos = new FileOutputStream(f); 
        fos.write(decoded); 
        fos.close(); 
       } catch (FileNotFoundException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

那麼好:

  var fileUp = document.getElementById("wsFile"); 
      var file = fileUp.files[0]; 

      var array = new Array(); 
      array = file.name.split("."); 


      var reader = new FileReader(); 
      reader.readAsDataURL(file); 

      if(array[array.length-1]=="zip" && file.size<=10000000){ 

       var xhr = new XMLHttpRequest(); 
       xhr.open("POST", "X",true); 
       xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 


       xhr.onreadystatechange = function() { 
        if(xhr.readyState == 4 && xhr.status == 200) { 
         dojo.byId("content").innerHTML=xhr.responseText; 
        } 
       } 
       reader.onload = function(){ 
        var params = "file="+ reader.result+"&fileName="+file.name; 
        xhr.send(params); 
       }; 

} 

服務器端(Spring MVC的) ,ajax請求成功並且服務器接收到客戶端發送的相同Base64字符串。 但是,當我嘗試提取zip內的文件時,出現損壞的歸檔消息。

我做錯了什麼或者這是一個zip壓縮檔案的限制? 對不起,任何天真的,但我從來沒有這樣做過

+0

'「服務器收到客戶端發送的相同的Base64字符串」「服務器是否從_Base64_生成相同的文件?雙方通過散列確認。 –

回答

3

翻翻你的代碼,我相信你不會送你認爲你發送!

這是由於這兩條線

reader.readAsDataURL(file); 
// and later 
var params = "file="+ reader.result+"&fileName="+file.name; 

考慮; readAsDataURL實際上產生了什麼?例如

var b = new Blob(['Hello World!'], {type: 'text/plain'}), 
    fr = new FileReader(); 
fr.onload = function() {console.log(this.result);}; 
fr.readAsDataURL(b); 
// data:text/plain;base64,SGVsbG8gV29ybGQh 

即你的reader.result不僅僅是Base64編碼數據,所以不正是你想要的

var base64Data = reader.result.slice(reader.result.indexOf(',') + 1); 
var params = "file=" + base64Data + "&fileName=" + file.name; 

注意,Base64編碼在我的例子是比文本它代表。這將始終如此,所以您可能需要考慮將該文件作爲二進制文件來代替;只需將file直接傳遞給send,其內容類型例如application/octet-stream,儘管這也意味着您的服務器代碼也需要更改,以瞭解它的反應。

+0

我試過了你在那裏的確切方式,當試圖打開zip存檔時,我得到「意外的存檔結束」,而WinRAR文件瀏覽器不顯示任何文件 –

+0

@NunoNeto請參閱[**此演示** http://jsbin.com/ahuzas/1/edit](http://jsbin.com/ahuzas/1/edit )我只是讓_JavaScript_接受你的文件,並讓你回到同一個文件的base64 dataURI鏈接。如果你仍然有問題,你需要做的是**記錄你得到的**,這樣你就可以調試哪一步沒有按預期工作。即記錄_JavaScript_中生成的base64,記錄Spring變量'file',並將輸入文件與解碼文件(文件長度,散列值)進行比較。 –

+0

這可能是因爲服務器簡單的事情就是修改接收到的數據,試圖解讀「表單數據」,所以要解決這個問題,在_JavaScript_你做一排'window.encodeURIComponent(base64Data)' –

1

我相信對於發送的zip文件,OCTET流應該用作內容類型。代碼中的另一個問題是,您只是將文件名稱作爲輸入。但要接收文件,您應該有文件的輸入流。你也應該發送文件內容,而不僅僅是文件的名稱。

如果您需要發送多個表單參數,例如文件元數據和實際文件內容,則應考慮使用Multipart/form或Multipart/mixed內容類型。

這是一個很好的使用球衣框架發送文件的教程。無論你使用的是什麼框架,但是你可以從例子中採取的學習收穫:

http://www.mkyong.com/webservices/jax-rs/file-upload-example-in-jersey/

+0

他們正在發送_String_,而不是_zip_ –

+0

@PaulS。是的,我想在我編輯的答案中提到另一個問題。編輯正在進行中:-) –

+0

我會在最初的帖子中明確說明 –

相關問題