【问题标题】:Send ZIP file to server in Base64 via POST通过 POST 将 ZIP 文件发送到 Base64 中的服务器
【发布时间】:2013-07-26 17:14:22
【问题描述】:

我正在尝试使用 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 存档的限制? 对不起,我之前从未这样做过

【问题讨论】:

  • "the server receives the same Base64 String that the client sent" 服务器是否从 Base64 生成相同的文件?通过两边哈希确认。

标签: java javascript ajax post base64


【解决方案1】:

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

因为这两行

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 比它所代表的文本。这始终是正确的,因此您可能需要考虑将文件作为 binary 发送;只需将file 直接传递给send,内容类型例如application/octet-stream,虽然这也意味着您的服务器代码也需要更改,以了解它的反应方式。

【讨论】:

  • 我已经尝试了与您完全相同的方式,当尝试打开 zip 存档时,我得到“存档意外结束”并且 WinRAR 文件资源管理器没有显示任何文件在那里
  • @NunoNeto 请参阅this demo http://jsbin.com/ahuzas/1/edit 我刚刚在 JavaScript 获取文件并返回同一文件的 base64 dataURI 链接的位置。如果您仍然遇到问题,您需要做的是记录您得到的结果,以便您可以调试哪个步骤未按预期工作。即记录 JavaScript 中生成的 base64,记录 Spring 变量 file,并将输入文件与解码文件(文件长度、任何哈希值)进行比较。
  • 这可能很简单,因为服务器正在修改接收到的数据以尝试解码“表单数据”,所以要修复它,在 JavaScript 中你可以 @ 987654333@
  • 连续第三条评论 -- 当然,我假设你正试图在 a browser that supports FileReader 上做这一切。 stackoverflow.com/questions/11089897/…
  • 我在 chrome 中尝试它,我也在检查浏览器是否支持 FileReader。我已经尝试过你的解决方案,除了 window.encodeURIComponent(base64Data),但我会再试一次,看看是否有更彻底的方法能产生任何结果,谢谢 ;)
【解决方案2】:

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

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

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

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

【讨论】:

  • 他们发送的是 String,而不是 zip
  • @PaulS。是的,我试图在我编辑的答案中提到另一个问题。正在编辑:-)
  • @JunedAhsan 我可能错了,但是通过将 zip 编码为 base64,我不是发送整个 zip 内容,包括其文件吗?我还发送了文件名,以便使用原始名称轻松保存
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 2014-05-10
  • 2014-09-09
  • 1970-01-01
相关资源
最近更新 更多