蚩尤后裔

芝兰生于深林,不以无人而不芳

H5的FormData详解

FormData简介

  1. FormData是Html5新加进来的一个类,可以模拟表单数据
  2. 利用 FormData 对象,可以通过JavaScript键值对来模拟一系列表单控件
  3. 可以使用JQuery的$.Ajax结合FormData异步上传二进制文件
  4. 可以先通过new关键字创建一个空的 FormData 对象,然后使用 append() 方法向该对象里添加字段(字段的值可以是一个 File对象或者字符串,剩下其他类型的值都会被自动转换成字符串)
  5. 也可以new的同时直接传入表单对象,从而创建有值的FormData对象

构造器

构造函数解释
FormData (optional HTMLFormElement form)(可选) 一个HTML表单元素,可以包含任何形式的表单控件,包括文件输入框.

方法

void append(DOMString name, DOMString value)

  • name 表单元素名称
  • value 表单元素要传递的值

项目实例

模拟表单

  1. FormData实际就是一个表单对象,所以可以用来直接封装表单数据

前台

    <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
    <script type="text/javascript">
        $(function(){
            $("#uploadButton").click(function(){

                /** 模拟一个简单的用户信息提交
                 * 这些数据平时都会放在页面让用户填写的
                 * 下面完全等价于<form>标签**/
                var formData = new FormData();
                formData.append("name","李四");
                formData.append("age",33);
                formData.append("sex",true);

                /**下面两个设置很关键,和平时使用时略有不同
                 * contentType: false->告诉jQuery不要去设置Content-Type请求头
                 * processData: false->告诉jQuery不要去处理发送的数据
                 */
                $.ajax({
                    url : "resourceController/test.action",
                    type: 'POST',
                    data: formData,
                    dataType:"JSON",
                    contentType: false,
                    processData: false,
                    success : function(data) {
                        console.log(JSON.stringify(data));
                        alert("上传成功")
                    },
                    error : function(data) {
                        console.log(JSON.stringify(data));
                        alert("上传失败");
                    }
                });
            });
        });

    </script>
</head>
<body>
<input type="button" id="uploadButton" value="提交">

后台

/** 测试使用,请删除
 * 后台接收和平时没有任何区别,可以单个命名接收,或者POJO对象直接自动封装接收
 * 下面是SpringMVC的接收方式,参数名必须与前台表单的name属性一致
 * @param name
 * @param age
 * @param sex
 * @param response
 */
@RequestMapping("test.action")
public void test(String name,String age,String sex, HttpServletResponse response) {
    try {
        response.setContentType("text/json;charset=UTF-8");
        PrintWriter printWriter = response.getWriter();
        JsonObject jsonObject = new JsonObject();

        System.out.println(name+":"+age+"::"+sex);

        printWriter.write(jsonObject.toString());
        printWriter.flush();
        printWriter.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

输出结果

单文件上传

前台

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试</title>
    <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
    <script type="text/javascript">
        $(function () {
            $("#uploadButton").click(function () {
                var fileInputJQ = $("input[name='uploadFileList']");
                if(fileInputJQ.val()==""){
                    alert("请先选择文件");
                    return;
                }
                /**直接使用FormData的有参构造器创建对象
                 * 注意里面的对象参数是DOM对象,而不是JQuery对象,所以必须要转
                 * 这样封装的是整个Form表单数据
                 **/
                var formData = new FormData($("#uploadForm")[0]);

                /**下面两个设置很关键,和平时使用时略有不同
                 * contentType: false->告诉jQuery不要去设置Content-Type请求头
                 * processData: false->告诉jQuery不要去处理发送的数据
                 * cache:缓存禁用不禁用,好像效果都一样
                 */
                $.ajax({
                    url: "resourceController/test.action",
                    type: 'POST',
                    data: formData,
                    cache:false,
                    dataType: "JSON",
                    contentType: false,
                    processData: false,
                    success: function (data) {
                        console.log(JSON.stringify(data));
                        alert("上传成功")
                    },
                    error: function (data) {
                        console.log(JSON.stringify(data));
                        alert("上传失败");
                    }
                });
            });
        });

    </script>
</head>
<body>

<%--文件上传时method必须是post,enctype必须是multipart/form-data--%>
<form id="uploadForm" method="post" enctype="multipart/form-data">
    <%--多文件上传时,加上multiple属性--%>
    <input type="file" name="multipartFile"/><br>
    描述<input type="text" name="info" placeholder="建议长度不超过20个字符" maxlength="20">
    <input type="button" id="uploadButton" value="上传">
</form>
</body>
</html>

后台

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.lct.domain.Client;
import com.lct.service.ClientService;
import com.lct.service.ResourceService;
import com.lct.utils.FileWmxUtils;
import com.lct.utils.UDPUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2018/3/8 0008.
 * 资源控制器
 */
@Controller
@RequestMapping("resourceController")
public class ResourceController {
/** 测试使用,请删除
 * 后台使用SpringMVC做文件上传,接收和平时没有任何区别,可以单个命名接收,或者POJO对象直接自动封装接收
 * 下面是SpringMVC的接收方式,参数名必须与前台表单的name属性一致
 * @param multipartFile:命名必须与前台file控件的name属性值一致
 * @param response:命名必须与前台Input控件name属性值一致
 */
@RequestMapping("test.action")
public void test(@RequestParam(required = true)MultipartFile multipartFile, String info,HttpServletResponse response) {
    try {
        response.setContentType("text/json;charset=UTF-8");
        PrintWriter printWriter = response.getWriter();
        JsonObject jsonObject = new JsonObject();

        System.out.println("文件名:"+multipartFile.getOriginalFilename());
        System.out.println("文件大小:"+FileUtils.byteCountToDisplaySize(multipartFile.getSize()));
        System.out.println("描述:"+info);

        multipartFile.transferTo(new File("E:/"+multipartFile.getOriginalFilename()));

        printWriter.write(jsonObject.toString());
        printWriter.flush();
        printWriter.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

输出结果


多文件上传

  1. 原理等同于单文件上传,只是按顺序逐个上传而已

前台

  1. 写法除了<input type='file'中加了multiple属性以外,其余的都和"单文件上传一致
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>测试</title>
    <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
    <script type="text/javascript">
        $(function () {
            $("#uploadButton").click(function () {
                var fileInputJQ = $("input[name='uploadFileList']");
                if(fileInputJQ.val()==""){
                    alert("请先选择文件");
                    return;
                }
                /**
                 * 直接使用FormData的有参构造器创建对象
                 * 注意里面的对象参数是DOM对象,而不是JQuery对象,所以必须要转
                 * 这样封装的是整个Form表单数据,无论是多文件还是单文件都是一致的
                 **/
                var formData = new FormData($("#uploadForm")[0]);

                /**下面两个设置很关键,和平时使用时略有不同
                 * contentType: false->告诉jQuery不要去设置Content-Type请求头
                 * processData: false->告诉jQuery不要去处理发送的数据
                 * cache:缓存禁用不禁用,好像效果都一样
                 */
                $.ajax({
                    url: "resourceController/test.action",
                    type: 'POST',
                    data: formData,
                    cache:false,
                    dataType: "JSON",
                    contentType: false,
                    processData: false,
                    success: function (data) {
                        console.log(JSON.stringify(data));
                        alert("上传成功")
                    },
                    error: function (data) {
                        console.log(JSON.stringify(data));
                        alert("上传失败");
                    }
                });
            });
        });

    </script>
</head>
<body>

<%--文件上传时method必须是post,enctype必须是multipart/form-data--%>
<form id="uploadForm" method="post" enctype="multipart/form-data">
    <%--多文件上传时,加上multiple属性--%>
    <input type="file" name="multipartFileArr" multiple/><br>
    描述<input type="text" name="info" placeholder="建议长度不超过20个字符" maxlength="20">
    <input type="button" id="uploadButton" value="上传">
</form>
</body>
</html>

后台

  1. 使用SpringMVC做单文件上传时,用的是单个MultipartFile对象,同理做多文件上传时只需要把它改成List或者Array即可
/** 测试使用,请删除
 * 后台使用SpringMVC做文件上传,接收和平时没有任何区别,可以单个命名接收,或者POJO对象直接自动封装接收
 * 下面是SpringMVC的接收方式,参数名必须与前台表单的name属性一致
 * @param multipartFileArr:命名必须与前台file控件的name属性值一致,多文件上上传时,用List或者Array即可
 * @param response:命名必须与前台Input控件name属性值一致
 */
@RequestMapping("test.action")
public void test(@RequestParam(required = true)MultipartFile[] multipartFileArr, String info,HttpServletResponse response) {
    try {
        response.setContentType("text/json;charset=UTF-8");
        PrintWriter printWriter = response.getWriter();
        JsonObject jsonObject = new JsonObject();

        for (MultipartFile multipartFile:multipartFileArr){
            System.out.println("文件名:"+multipartFile.getOriginalFilename());
            System.out.println("文件大小:"+FileUtils.byteCountToDisplaySize(multipartFile.getSize()));
            System.out.println("描述:"+info);
            multipartFile.transferTo(new File("E:/"+multipartFile.getOriginalFilename()));
        }
        printWriter.write(jsonObject.toString());
        printWriter.flush();
        printWriter.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

测试输出



阅读更多
文章标签: java FormData
个人分类: 文件上传 Html 5
上一篇$.ajax多文件上传详解
下一篇MySQL存储引擎详解
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭