ajax通过FormData构造form表单异步提交

前言

做个web开发的都知道,使用常规的form表单提交,会存在页面跳转的问题,之前也写过一篇博文《如何实现form表单提交和ajax异步操作相似效果》,那么,今天主要是介绍一种更正统的写法,使用html5 FormData实现表单的异步提交操作,例如:文件上传等。

代码示例

  1. 直接创建FormData对象

    html文件:
    <html>
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>FormData使用示例</title>
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
    <script src="${resourceUrl}/javascript/jquery.min.js"></script>
    <script src="${resourceUrl}/javascript/myfile.js"></script>
    </head>
    <body class="sidebar-mini skin-black-light">
    <p>ajax通过FormData构造form表单异步文件上传:</p>
    <input type="file" id="myfile" name="myfile" onchange="asyncUploadFile(this);" />
    </body>
    </html>

    myfile.js:

    //上传的函数
    function asyncUploadFile(target) {
    var $target = $(target);// 将dom节点转换为JQuery对象
    var formData = new FormData();
    formData.append("file", $target.prop('files')[0]);
    formData.append("paramName2", "paramValue2");
    formData.append("paramName3", "paramValue3");//类似form表单一样添加参数
    $.ajax({
    type : 'POST', //指定http请求类型
    processData : false, // tell jQuery not to process the data
    contentType : false, // tell jQuery not to set contentType
    data : formData,
    url : '/uploadFile',
    dataType : 'json',
    success : function(result) {
    console.log(result);
    },
    error : function(result) {
    console.log(result);
    }
    });
    }

    ps:由于是<input type="file"/>是单选的,可以通过$target.prop('files')[0]来获取选中的文件,
    多选的话则需要遍历$target.prop('files')对象;
  2. 根据已经存在的form表单创建FormData对象

    html文件:
    <div>
    <p>ajax根据已经存在的form表单创建FormData对象,异步文件上传:</p>
    <form id= "uploadForm">
    <p>选择文件:<input type="file" id="myfile" name="myfile"/></p>
    <p>推广渠道:<input type="text" id="channel" name="channel"/></p>
    <input type="button" value="提交" onclick="asyncUpload();" />
    </form>
    </div>
    ps: 不再使用submit类型提交表单[<button type="submit">提交</button>]

    myfile.js:

    // 实现页面无刷新,异步提交表单 - 再也不需要搞一个隐藏的iframe实现页面无刷新提交表单了
    function asyncUpload() {
    var checkResult = checkParam();//表单提交前进行参数校验
    if(checkResult){
    var formData = new FormData($("#uploadForm")[0]);
    $.ajax({
    type : 'POST', //指定http请求类型
    processData : false, // tell jQuery not to process the data
    contentType : false, // tell jQuery not to set contentType
    data : formData,
    url : '/uploadData',
    dataType : 'json',
    success : function(result) {
    console.log(result);
    },
    error : function(result) {
    console.log(result);
    }
    });
    } else {
    console.log(checkResult);
    }
    }

    // 参数校验
    function checkParam() {
    if(不合法){
    return false;
    }
    return true;
    }

总结

在html5 FormData出来之前,ajax是无法异步提交二进制文件的,那时候的一种折中处理方案是将二进制文件base64编码成字符串,然后再用ajax进行异步上传。或者就只能通过form表单提交的方式上传二进制文件(存在页面跳转的问题),所以,FormData的出现算是一大福音,但是由于浏览器的兼容性,还未能广泛使用。使用条件:jquery的版本要在2.0以上,而且一般低版本浏览器不支持FormData,所以目前不可在生产环境中使用,仅能在一些无关紧要的后台系统中尝试一下。

参考链接

  1. https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/FormData
  2. https://developer.mozilla.org/zh-CN/docs/Web/API/FormData/Using_FormData_Objects