1

我正在尝试使用 ajax 请求将包含多个文件的 zip 从客户端发送到服务器。zip 在 javascript 中编码为 Base64 字符串并作为 post 参数传递

Javascript代码:

            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):

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

到目前为止一切顺利,ajax 请求成功,服务器接收到与客户端发送的相同的 Base64 字符串。但是,当我尝试提取 zip 中的文件时,我收到一条损坏的存档消息。

我做错了什么还是这是 zip 档案的限制?对不起任何天真,但我以前从未这样做过

4

2 回答 2

2

查看您的代码,我相信您没有发送您认为发送的内容!

这是由于这两行

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,尽管这也意味着您的服务器代码也需要更改,以了解它的反应方式。

于 2013-07-26T17:28:35.203 回答
0

我相信对于发送 zip 文件,应该使用 OCTET 流作为内容类型。代码中的另一个问题是您只是将文件名作为输入。但是要接收文件,您应该拥有该文件的输入流。此外,您应该发送文件内容而不仅仅是文件名。

如果您需要随请求发送多个表单参数,例如文件元数据和实际文件内容,则应考虑使用 Multipart/form 或 Multipart/mixed 内容类型。

这是使用 jersey 框架发送文件的好教程。无论您使用什么框架,您都可以从示例中吸取教训:

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

于 2013-07-26T17:15:54.150 回答