Input表单写法:
multiple选项用于声明是批量上传 accept声明只接收jpg格式的图片,其他格式的文件在选项卡中显示不出来
来自:http://www.cnblogs.com/kissdodog/archive/2012/12/15/2819025.html
一、ajaxFileUpload是一个异步上传文件的jQuery插件。
传一个不知道什么版本的上来,以后不用到处找了。
语法:$.ajaxFileUpload([options])
options参数说明:
1、url 上传处理程序地址。
2,fileElementId 需要上传的文件域的ID,即的ID。
3,secureuri 是否启用安全提交,默认为false。
4,dataType 服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
5,success 提交成功后自动执行的处理函数,参数data就是服务器返回的数据。
6,error 提交失败自动执行的处理函数。
7,data 自定义参数。这个东西比较有用,当有数据是与上传的图片相关的时候,这个东西就要用到了。
8, type 当要提交自定义参数时,这个参数要设置成post
错误提示:
1,SyntaxError: missing ; before statement错误
如果出现这个错误就需要检查url路径是否可以访问
2,SyntaxError: syntax error错误
如果出现这个错误就需要检查处理提交操作的服务器后台处理程序是否存在语法错误
3,SyntaxError: invalid property id错误
如果出现这个错误就需要检查文本域属性ID是否存在
4,SyntaxError: missing } in XML expression错误
如果出现这个错误就需要检查文件name是否一致或不存在
5,其它自定义错误
大家可使用变量$error直接打印的方法检查各参数是否正确,比起上面这些无效的错误提示还是方便很多。
使用方法:
引入jQuery与ajaxFileUpload插件。注意先后顺序,这个不用说了,所有的插件都是这样。
一个例子:
![上传成功啦]()
ajaxFileUpload插件原理其实构建了一个表单form,里面很多file用于上传:最后submit()表单:见下面部分源码
var form = jQuery('');
if (data) {
for ( var i in data) {
jQuery('').appendTo(form);
}
}
提交函数:
function uploadHeadPhoto(){
var userId = $("#userId",navTab.getCurrentPanel()).val();;
if (userId == null) {
alertMsg.error("请选择用户ID"); //dwz框架
return;
}
//必须上传图片,才能注册
var newHeadPhoto = $("#newPhoto",navTab.getCurrentPanel()).val();
if (newHeadPhoto != null && newHeadPhoto != '') {
if (newHeadPhoto.toLowerCase().indexOf('.jpg') < 0) {
alertMsg.error("请上传JPG文件");
return;
};
} else {
alertMsg.error('请添加头像照片');
return;
}
var albumId = $("#albumId",navTab.getCurrentPanel()).val();
if (albumId == null || albumId=='') {
alertMsg.error("头像所属相册编号为空");
return;
}
//加载缓冲效果
//对应html页面的: ";
additionalRecord += record;
}
//加载到该显示的地方
var headPhotoListTD=$("#headPhotoList",navTab.getCurrentPanel());
var orignalRecord = headPhotoListTD.html();
headPhotoListTD.html(orignalRecord + additionalRecord);
},
error : function(data, status, e) {
alertMsg.info(e);
}
});
}
$("#loading",navTab.getCurrentPanel()).ajaxStart(function() {
$(this).show();
}).ajaxComplete(function() {
$(this).hide();
});
$.ajaxFileUpload({
url : 'uploadMultiHeadPhoto.do', //服务器url
data : {
"albumId" : albumId,
"userId" : userId
},
secureuri : false,
fileElementId : 'newPhoto',
dataType : 'json',
success : function(data, status) {
var photoList = eval("(" + data.message + ")");
var additionalRecord = '';
//将解析出来的图像上传后的url,上传状态做显示
for(var i=0 ;i
SpringMVC框架后台接收:
@RequestMapping(value = "uploadMultiHeadPhoto.do")
@ResponseBody
public AjaxResponseBean uploadMultiHeadPhoto(
@ModelAttribute("userInfoBean") UserInfoBean userBean,
HttpServletRequest request, HttpServletResponse response, ModelMap map) {
UserInfoBean:
private List newPhoto;
保存图片到本地并返回Listpublic static List saveFileList(List multipartFiles, String parent, String extend) throws Exception {
List files = new ArrayList<>();
if(parent == null){
// 保存文件的父目录
parent = makeParentDirectory();
}
if (multipartFiles == null || multipartFiles.size()<=0) {
return null;
}
for(MultipartFile multipartFile : multipartFiles){
String originalFilename = multipartFile.getOriginalFilename();
if(StringUtil.isNotBlank(originalFilename)){
int index = originalFilename.lastIndexOf(".");
if(index > 0){
extend = originalFilename.substring(index);
}
}
// 生成一个随机数,保证同一时间 也不会生成相同的文件名
int temp = (int)Math.random() *1000;
String fileName = MD5.getMD5(originalFilename + temp + DateUtil.dateToString(new Date(),Format.YYYY_MM_DD_HH_MM_SS_SSS));
String savePath = parent +File.separator + fileName + extend;
File localFile = new File(savePath);
try {
multipartFile.transferTo(localFile);
files.add(localFile);
} catch (IllegalStateException e) {
throw e;
} catch (IOException e) {
throw e;
}
}
return files;
}
可以将List
2015-11-13补充:
之前代码是适用于一个file字段,在选图片的时候可以选择多张。
由于业务需求,需要上传多个file字段。上述直接用$.ajaxFileUpload({});这种方式明显不合适,因为fileElementId只能是一个字段
这时需要我们修改ajaxFileUpload框架。
源码如下:(位置ajaxfileupload.js)
构造隐藏form字段的代码:
createUploadForm : function(id, fileElementId, data) {
//create form
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
//构造form字段
var form = jQuery('');
//循环遍历构造普通input字段
if (data) {
for ( var i in data) {
jQuery(
'').appendTo(form);
}
}
//构造file字段
var oldElement = jQuery('#' + fileElementId);
var newElement = jQuery(oldElement).clone();
jQuery(oldElement).attr('id', fileId);
jQuery(oldElement).before(newElement);
jQuery(oldElement).appendTo(form);
//set attributes
jQuery(form).css('position', 'absolute');
jQuery(form).css('top', '-1200px');
jQuery(form).css('left', '-1200px');
jQuery(form).appendTo('body');
return form;
},
结合这段应用代码(批量用一个file字段上传多张照片,ctrl+多选,成功之后返回路径并显示)
$.ajaxFileUpload({
url : 'uploadMultiHeadPhoto.do', //uploadHeadPhoto
data : {
"albumId" : albumId,
"userId" : currentMajiaUserId
},
secureuri : false,
fileElementId : 'newPhoto',
dataType : 'json',
success : function(data, status) {
var photoList = eval("(" + data.message + ")");
var additionalRecord = '';
for(var i=0 ;i ";
additionalRecord += record;
}
var headPhotoListTD=$("#headPhotoList",navTab.getCurrentPanel());
var orignalRecord = headPhotoListTD.html();
headPhotoListTD.html(orignalRecord + additionalRecord);
},
error : function(data, status, e) {
alertMsg.info(e);
}
});
可以看到普通input字段,源码是循环遍历处理的,于是我们要修改的也是讲下面处理file字段的代码也循环处理
但是考虑到之前的代码全是一个file字段,所以要判断file字段是不是一个数组具体代码如下:
createUploadForm : function(id, fileElementId, data) {
//create form
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
//构造form字段
var form = jQuery('');
//循环遍历构造普通input字段
if (data) {
for ( var i in data) {
jQuery(
'').appendTo(form);
}
}
//构造file字段
//var oldElement = jQuery('#' + fileElementId);
//var newElement = jQuery(oldElement).clone();
//jQuery(oldElement).attr('id', fileId);
//jQuery(oldElement).before(newElement);
//jQuery(oldElement).appendTo(form);
//为了兼容以前没有的代码(以前用到了file只是一个字段)所以添加是否是数组的判断条件
if(fileElementId instanceof Array){
for(var i in fileElementId){
var oldElement = jQuery('#' + fileElementId[i]);
var newElement = jQuery(oldElement).clone();
jQuery(oldElement).attr('id', fileId);
jQuery(oldElement).before(newElement);
jQuery(oldElement).appendTo(form);
}
}else{
var oldElement = jQuery('#' + fileElementId);
var newElement = jQuery(oldElement).clone();
jQuery(oldElement).attr('id', fileId);
jQuery(oldElement).before(newElement);
jQuery(oldElement).appendTo(form);
}
//set attributes
jQuery(form).css('position', 'absolute');
jQuery(form).css('top', '-1200px');
jQuery(form).css('left', '-1200px');
jQuery(form).appendTo('body');
return form;
},
注意下面问题:
测试的过程我发现如下问题:
1、如果for( var i in fileElementId ) 如果fileElementId不是一个数组,会报错!!所以要加判断条件
2、如果你有定义了多个file字段,结合上面的应用代码
比如:
$.ajaxFileUpload({
url : 'addEasemobPushTask.do', //uploadHeadPhoto
data : $('#broadcastForm').serialize(),
secureuri : false,
fileElementId : ['images','videos','videosShot'],
dataType : 'json',
success : function(data, status) {
alert("提交成功");
},
error : function(data, status, e) {
alertMsg.info(e);
}
});
定义了三个字段,如果有个字段(比如images)为空,那么传到后台照样会有MultipartFile字段(private MultipartFile images,也就是images!=null),只是这个字段的大小为0
所以如果我们要动态去拼凑这个数组,不要将所有可能的字段都定义进去。
3、fileElementId 可以是[] 空数组,一个元素的数组,甚至一个元素
4、由于它是构造一个表单,普通input字段的构造方法如下:
if (data) {
for ( var i in data) {
jQuery(
'').appendTo(form);
}
}
这样可以看到问题了,如果data[i]的值中包含双引号" 呢??
那么就会在引号那里被截断
解决方法是替换所有的双引号变成 "
if(content != null || content!=""){
content = content.replace(/\"/g,""");
}
我的多file字段批量上传应用代码:
function addEasemobPushTask(){
//定义file字段数组
var fileElements = [];
$("#tip_message").text("");
var userIds = $("#receivedExcelFile").val();
var sendId = $("#sendId").val(); //发送者ID
if (userIds == null || userIds == "") {
$("#tip_message").text("请添加接受者Excel文件");
return false;
}
if (sendId == null || sendId == "") {
$("#tip_message").text("请添加发送者ID");
return false;
}
if (userIds != null && userIds != '') {
if (userIds.toLowerCase().indexOf("xls") < 0
&& userIds.toLowerCase().indexOf("xlsx") < 0) {
alert("请上传excel文件");
return;
}
}
var minTime = $("#minTime").val();
var maxTime = $("#maxTime").val();
var msgType = $("#msgType").val();
//富文本消息
var content = $("#content").val();
//图文链接消息
var linkTitle = $("#linkTitle").val();
var linkAddr = $("#linkAddr").val();
var linkContent = $("#linkContent").val();
var linkImages = $("#linkImages").val();
//图片消息
var images = $("#images").val();
//语音消息
var audios = $("#audios").val();
//视频消息
var videos = $("#videos").val();
var videosShot = $("#videosShot").val();
//添加到数组
fileElements.push("receivedExcelFile");
//富文本消息-->系统提示消息
if(msgType == 1 || msgType == 11){
//....
}else if(msgType == 23){
//...
}else if(msgType == 21){
}else if(msgType == 31){
}else if(msgType == 41){
//富文本消息
$("#content").val("");
//图文链接消息
$("#linkTitle").val("");
$("#linkAddr").val("");
$("#linkContent").val("");
$("#linkImages").val("");
//图片消息
$("#images").val("");
//语音消息
$("#audios").val("");
if(videos == null || videos == ""){
$("#tip_message").text("视频文件不能为空");
return;
}
if(videosShot == null || videosShot == ""){
$("#tip_message").text("视频文件缩略图不能为空");
return;
}
fileElements.push("videos");
fileElements.push("videosShot");
}
//提交表单
$.ajaxFileUpload({
url : 'addEasemobPushTask.do', //uploadHeadPhoto
data : {
"msgType" : msgType,
"sendId" : sendId,
"minTime" : minTime,
"maxTime" : maxTime,
"content" : content,
"linkTitle" : linkTitle,
"linkAddr" : linkAddr,
"linkContent" : linkContent
},
secureuri : false,
fileElementId : fileElements,
dataType : 'json',
success : function(data, status) {
alert("提交成功");
},
error : function(data, status, e) {
alertMsg.info(e);
}
});
}
省略其他选项卡的处理内容!!!
补充:
之前提到过一个主意事项,就是如果普通表单有双引号的问题,有双引号如果在构建的时候会截断字符串,之前的处理是在每个可能出现的地方都替换了双引号 变成"
这样就有很多顾虑,而且可能要处理很多字段,倒不如直接在ajaxfileupload.js 中替换来的干脆:
//循环遍历构造普通input字段
if (data) {
for ( var i in data) {
//因为拼凑时如果有双引号会截断字符串,于是这里把双引号替换掉
//2016-01-07
//author:dhh
var formData = data[i].replace(/\"/g,"""); //直接在这里处理掉每个字段
jQuery(
'').appendTo(form);
}
}