通过Ajax使用FormData对象无刷新上传文件方法


Posted in Javascript onDecember 08, 2016

写在前面:本文说的这个方案有浏览器兼容性问题;所有主流浏览器的较新版本已经支持这个对象了,比如Chrome 7+、Firefox 4+、IE 10+、Opera 12+、Safari 5+,对兼容性比较敏感的网站慎用。

在工作中遇到了一个问题:在一个页面中,有4块内容,每块内容都包含一个图片上传功能,希望可以实现一键把这四块内容都上传上去。

我没有用插件实现上传功能,就是用的input[type=file],因此就遇到一个问题就是:

①传统的form表单会导致页面刷新,无法实现上述功能

②把表单serialize()序列化用Ajax的方式提交,也无法把上传文件的文件流进行序列化,也不行

我现有的知识就搞不定了,只能求助网上的大神了,百度了一下,大概看了两个方案:

①在js中创建一个新form表单,把页面中原form表单copy一份,然后再用js搞一个iframe,把form表单的target设置为iframe,这样提交后返回的内容就在iframe里,最后再把form表单、iframe移除

②就是本文下面要说的使用FormData对象实现

有其他思路方案的希望不吝赐教!

好,介绍完背景之后,开始介绍我们今天的主题:FormData对象。

有两种方式可以创建一个FormData对象:

①创建一个空的FormData对象,然后使用append()方法向该对象里添加字段

②使用HTML表单来初始化一个FormData对象

下面分别介绍一下:

第一种方式:

var oMyForm = new FormData();
oMyForm.append("username", "Groucho");
oMyForm.append("accountnum", 123456); 
oMyForm.append("file", $('#file')[0].files[0]);

$.ajax({
 url: '/Manage/UploadImg',
 type: 'POST',
 cache: false,
 data: oMyForm,
 processData: false,
 contentType: false,
 async: false
}).done(function(res) {}).fail(function(res) {});

第二种方式:

<form id="uploadForm" enctype="multipart/form-data">
 <p>指定文件名: <input type="text" name="filename" value="" /></p>
 <p>上传文件: <input type="file" name="file" /></ p>
  <input type="button" value="上传" onclick="doUpload()" />
</form>
var formData = new FormData($('#uploadForm')[0]);
formData.append('num', '1');//可以在已有表单数据的基础上,继续添加新的键值对
$.ajax({
 url: '/upload',
 type: 'POST',
 cache: false,
 data: new FormData($('#uploadForm')[0]),
 processData: false,
 contentType: false
}).done(function(res) {}).fail(function(res) {});

注意:

  • Ajax的processData设置为false。因为data值是FormData对象,不需要对数据做处理。
  • 第二种方式中<form>标签加enctyp

    e="multipart/form-data"属性。

  • cache设置为false,上传文件不需要缓存。
  • contentType设置为false。因为是由<form>表单构造的FormData对象,且已经声明了属性enctype="mutipart/form-data",所以这里设置为false。

前端搞定之后,剩下的就是后端处理了。ok,就到这里了。

FormData对象,是可以使用一系列的键值对来模拟一个完整的表单,然后使用XMLHttpRequest发送这个"表单"。

在 Mozilla Developer 网站 使用FormData对象 有详尽的FormData对象使用说明。

但上传文件部分只有底层的XMLHttpRequest对象发送上传请求,那么怎么通过jQuery的Ajax上传呢?

本文将介绍通过jQuery使用FormData对象上传文件。

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

HTML代码

<form id="uploadForm" enctype="multipart/form-data">
 <input id="file" type="file" name="file"/>
 <button id="upload" type="button">upload</button>
</form>

JavaScript代码

$.ajax({
 url: '/upload',
 type: 'POST',
 cache: false,
 data: new FormData($('#uploadForm')[0]),
 processData: false,
 contentType: false
}).done(function(res) {
}).fail(function(res) {});

这里要注意几点:

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

上传后,服务器端代码需要使用从查询参数名为file获取文件输入流对象,因为<input>中声明的是name="file"。

如果不是用<form>表单构造FormData对象又该怎么做呢?

使用FormData对象添加字段方式上传文件

HTML代码

<div id="uploadForm">
 <input id="file" type="file"/>
 <button id="upload" type="button">upload</button>
</div>

这里没有<form>标签,也没有enctype="multipart/form-data"属性。

javascript代码

var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);
$.ajax({
 url: '/upload',
 type: 'POST',
 cache: false,
 data: formData,
 processData: false,
 contentType: false
}).done(function(res) {
}).fail(function(res) {});

这里有几处不一样:

  • append()的第二个参数应是文件对象,即$('#file')[0].files[0]。
  • contentType也要设置为‘false'。

从代码$('#file')[0].files[0]中可以看到一个<input type="file">标签能够上传多个文件,只需要在<input type="file">里添加multiple或multiple="multiple"属性。

服务器端读文件

从Servlet 3.0 开始,可以通过 request.getPart() 或 request.getPars() 两个接口获取上传的文件。

这里不多说,详细请参考官网教程 Uploading Files with Java Servlet Technology 以及示例The fileupload Example Application

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
检测input每次的输入是否合法遇到汉字输入就有问题
May 23 Javascript
基于jquery打造的百分比动态色彩条插件
Sep 19 Javascript
验证手机号码的JS方法分享
Sep 10 Javascript
javascript批量修改文件编码格式的方法
Jan 27 Javascript
js实现数字每三位加逗号的方法
Feb 05 Javascript
跟我学习javascript的var预解析与函数声明提升
Nov 16 Javascript
整理关于Bootstrap表单的慕课笔记
Mar 29 Javascript
原生js实现密码输入框值的显示隐藏
Jul 17 Javascript
Vue渲染函数详解
Sep 15 Javascript
js实现点击图片在屏幕中间弹出放大效果
Sep 11 Javascript
微信小程序实现限制用户转发功能的实例代码
Feb 22 Javascript
基于vue实现探探滑动组件功能
May 29 Javascript
js倒计时小实例(多次定时)
Dec 08 #Javascript
详解JavaScript中的属性和特性
Dec 08 #Javascript
微信小程序开发之视频播放器 Video 弹幕 弹幕颜色自定义实例
Dec 08 #Javascript
AngularJS模仿Form表单提交的实现代码
Dec 08 #Javascript
解析如何利用iframe标签以及js制作时钟
Dec 08 #Javascript
详解微信小程序 页面跳转 传递参数
Dec 08 #Javascript
浅谈javascript中执行环境(作用域)与作用域链
Dec 08 #Javascript
You might like
逐步提升php框架的性能
2008/01/10 PHP
在JavaScript中调用php程序
2009/03/09 PHP
关于mysql字符集设置了character_set_client=binary 在gbk情况下会出现表描述是乱码的情况
2013/01/06 PHP
用Zend Studio+PHPnow+Zend Debugger搭建PHP服务器调试环境步骤
2014/01/19 PHP
推荐10 款 SVG 动画的 JavaScript 库
2015/03/24 Javascript
JavaScript实现数字数组按照倒序排列的方法
2015/04/06 Javascript
js实现无缝滚动特效
2015/12/20 Javascript
详解AngularJS过滤器的使用
2016/03/11 Javascript
JS获取屏幕高度的简单实现代码
2016/05/24 Javascript
js制作网站首页图片轮播特效代码
2016/08/30 Javascript
Vue数据驱动模拟实现4
2017/01/12 Javascript
vue2.0 父组件给子组件传递数据的方法
2018/01/15 Javascript
js删除数组中的元素delete和splice的区别详解
2018/02/03 Javascript
javascript实现最长公共子序列实例代码
2018/02/05 Javascript
使用mint-ui实现省市区三级联动效果的示例代码
2018/02/09 Javascript
如何让node运行es6模块文件及其原理详解
2018/12/11 Javascript
微信小程序 弹窗输入组件的实现解析
2019/08/12 Javascript
Pyhton中防止SQL注入的方法
2015/02/05 Python
python根据出生日期获得年龄的方法
2015/03/31 Python
python基础while循环及if判断的实例讲解
2017/08/25 Python
Django model反向关联名称的方法
2018/12/15 Python
python实现转盘效果 python实现轮盘抽奖游戏
2019/01/22 Python
Python中print和return的作用及区别解析
2019/05/05 Python
浅析python中的del用法
2020/09/02 Python
pymysql模块使用简介与示例
2020/11/17 Python
欧洲顶级的童装奢侈品购物网站:Bambini Fashion(面向全球)
2018/04/24 全球购物
美国最大的在线寄售和旧货店:Swap.com
2018/08/27 全球购物
商务英语专业应届毕业生求职信
2013/10/28 职场文书
学年末自我鉴定
2014/01/21 职场文书
幼儿园教育教学反思
2014/01/31 职场文书
个人近期表现材料
2014/02/11 职场文书
应届大专毕业生自我鉴定
2014/04/08 职场文书
物业消防安全责任书
2014/07/23 职场文书
大学生党员个人对照检查材料范文
2014/09/25 职场文书
【海涛解说】暗牧也疯狂,牛蛙成配角
2022/04/01 DOTA
Apache自带的ab压力测试工具的实现
2022/07/23 Servers