通过jQuery Ajax使用FormData对象上传文件,Grails读取FormData数据

参考许多文章,结合自己所需,备份

目的:在后台获取文件,以下是gsp页面内容

<g:form action="save" method="post" id="searchForm" enctype="multipart/form-data">
    <div class="form-group">
        <div class="label"><label>姓名</label></div>
        <input type="user" id="user" name="user"/>
    </div>
    <div class="form-group">
        <div class="label"><label>文件</label></div>
        <input type="file" id="file" name="file"/>
        <input type="submit" value="上传"/>
    </div>
</g:form>

注:enctype=”multipart/form-data” 必须要写

有一种最直接了当的方式得到文件内容,上传,以下是NewsController代码

def save={
    def file = request.getFile('file');
    if (!file .empty){
        def filename = file.originalFilename;//得到文件名
        def rootDir = servletContext.getRealPath("/");//得到上传文件的保存目录
        def uDir=new File(rootDir,"/load/");
        //判断上传文件的保存目录是否存在
        if (!uDir.exists() && !uDir.isDirectory()) {
            println(uDir+"目录不存在,需要创建");
            //创建目录
            userDir.mkdirs();
        }       
        int index = filename.lastIndexOf("."); //取得文件名中最后一个"."的索引 
        def newext = filename.substring(i); //获取文件扩展名此时可对文件拓展名做一些限制,比如照片格式,文档格式,媒体格式等
        file.transferTo( new File( uDir, filename));    
        render action:~    
    }   
}

但是这个时候页面也跟着刷新,在有些情况下,我们不希望页面被刷新,这种时候我们都是使用Ajax的方式进行请求的:

$.ajax({
    url:"<%=request.getContextPath()%>/news/save",
    type:'POST',
    data:{user:$('#user').val()},
    dataType:'json',
    error:function () {
        alert('提交错误');
    },
    cache:false,
    success:function (msg) {
        alert(成功);
    }
});

但是上述方式,只能传递一般的参数,比如String类型的user,上传文件的文件流是无法传递的。
不过现在有一种方法,通过FormData对象可以传递任何类型的数据,轻松地使用Ajax方式进行文件上传了。

首先先学习如何使用FormData

FormData对象,是可以使用一系列的键值对来模拟一个完整的表单,通过jQuery使用FormData对象上传文件。参考文章

使用form表单初始化FormData对象方式上传文件


$.ajax({
    url:"<%=request.getContextPath()%>/news/save",
    type: 'POST',
    cache: false,
    data: new FormData($('#searchForm')[0]),
    processData: false,
    contentType: false,
    error:function () {
        alert('错误!');
    },
    success:function (msg) {
        alert('成功');
    }
});

注意:

  1. processData设置为false。因为data值是FormData对象,不需要对数据做处理。
  2. form标签添加enctype=”multipart/form-data”属性。
  3. cache设置为false,上传文件不需要缓存。
  4. contentType设置为false。因为是由form表单构造的FormData对象,且已经声明了属性enctype=”multipart/form-data”,所以这里设置为false。

使用form对象初始化FormData对象方式上传文件

html:

<div>
    <div class="form-group">
        <div class="label"><label>姓名</label></div>
        <input type="user" id="user" name="user"/>
    </div>
    <div class="form-group">
        <div class="label"><label>文件</label></div>
        <input type="file" id="file" name="file"/>
        <input type="submit" value="上传"/>
    </div>
</div>

JavaScript:

var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);
formData.append('user',$('#user'));
$.ajax({
     url:"",
     type: 'POST',
     cache: false,
     data: formData,
     processData: false,
     contentType: false,
     error:function () {
         alert('错误!');
     },
     success:function (msg) {
         alert(msg.file+msg.user);
     }
 });

这里有几处不一样:

  • append()的第二个参数应是文件对象,即$(‘#file’)[0].files[0]

  • contentType也要设置为‘false

  • 从代码$(‘#file’)[0].files[0]中可以看到一个input标签能够上传多个文件,只需在input添加multiple或multiple=”multiple”属性。

FormData传递数据,Grails读取数据

服务器端读取数据跟NewsController代码一样,因为FormData通过键值对的形式传递到服务器,因此只需

def fileName = params.file;
def userName = params.user;

就读到了数据内容

你可能感兴趣的:(jquery,jquery,Ajax,Ajax,上传文件,grails)