使用Jquery的Ajax异步提交有二进制数据的表单实现方案

Binary格式上传文件
1.form-data、x-www-form-urlencoded、raw、binary的区别
form-data:

http请求中的multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。当上传的字段是文件时,会有Content-Type来说明文件类型;content-disposition,用来说明字段的一些信息;

由于有boundary隔离,所以multipart/form-data既可以上传文件,也可以上传键值对,它采用了键值对的方式,所以可以上传多个文件。
x-www-form-urlencoded:

就是application/x-www-from-urlencoded,会将表单内的数据转换为键值对,比如,name=java&age = 23
raw:

可以上传任意格式的文本,可以上传text、json、xml、html等
binary :

相当于Content-Type:application/octet-stream,从字面意思得知,只可以上传二进制数据,通常用来上传文件,由于没有键值,所以,一次只能上传一个文件
————————————————
版权声明:本文为CSDN博主「一滴水的眼泪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_35112567/article/details/106818545

在公司的项目中,遇到一个需求,需要异步提交包含二进制数据的表单,也就是含有type="file"的input的form表单。异步提交表单我想对于大家都应该是件“so easy”的事情,也就是首先监听表单的submit事件,然后在回调函数里面获取表单的数据,然后通过ajax发出请求,最后记得一定要返回false来阻止默认表单的提交。示例如下:

//监听表单提交,变为异步提交表单
$("#importForm").on("submit", function(event){
    var form = this;
    //获取表单序列化字符串,
    //也就是将整个表单的输入数据转换为以&作为分隔符的多个key=value的字符串
    var formData = $(form).serialize();
    $.ajax({
        //获取表单的action作为url
        url: form.action,
        type: "POST",
        data: formData,//把序列化后的表单数据放到这里
        dataType: "JSON",
        async: true,
        error: function(xhr,status,error){
            alert("请求出错!");
        },
        success: function(result){
            alert("表单提交成功!");
        }
    });
    //这里一定要返回false来阻止表单的submit
    return false;
});

 

但是在实施的过程却发现,表单的确是能异步提交,但是表单中的file类型的input却没有提交到后台。后来发现,原来是在序列化表单数据这一步出了问题,表单中的二进制数据不能被序列化成字符串。想想也对,二进制数据怎么能被序列化为字符串呢?那为什么默认的submit动作又可以获取到二进制数据,并且能成功的提交到后台呢?

我想可能是因为我们前面不是设了表单的enctype="multipart/form-data"吗,那么submit的时候浏览器就会识别到表单中有二进制数据,然后就会采用正确的方式获取表单数据,用正确的contentType来提交数据。然而我们自己写的异步提交,无论表单有没有二进制数据,都直接粗暴的把表单序列化,然后提交序列化后的数据,这样当然不行的啊。百度一番后,原来通过html5的FormData对象对带有二进制数据的表单进行构造,然后通过ajax发送这个构造好的FormData就可以实现异步提交了。废话不多说,送上代码:

//监听表单提交,变为异步提交表单
$("#importForm").on("submit", function(event){
    var form = this;//this代表的就是当前提交表单的DOM对象
    //用H5的FormData对象对表单数据进行构造
    var formData = new FormData(form);//FormData构造器接收的是一个form的DOM对象

    $.ajax({
        url: this.action,
        type: "POST",
        data: formData,
        dataType: "JSON",
        async: true,
        //要想用jquery的ajax来提交FormData数据,
        //则必须要把这两项设为false
        processData: false,
        contentType: false,
        //这里是防表单重复提交,可以忽略
        beforeSend: function(xhr){
            $("#importForm :submit").attr("disabled",true);
        },
        complete: function(xhr,status){
            $("#importForm :submit").attr("disabled", false);
        },
        error: function(xhr,status,error){
            alert("请求出错!");
        },
        success: function(result){
            alert("表单提交成功!");
        }
    });

    //阻止表单的提交事件
    return false;
});

  

然后重点的是processData: false, contentType: false这两句,因为这里采用的是jquery的ajax进行发送请求,jquery会默认对请求的数据和请求的类型进行处理,比如processData不设为false,jquery就会对请求数据进行序列化,contentType不设为false,默认是:"application/x-www-form-urlencoded".很明显,提交二进制数据肯定不能用这种contentType,因为这种是用来提交key=value形式的参数的.
————————————————
版权声明:本文为CSDN博主「开发很忙」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_16148137/article/details/51853886

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值