ajax批量上传图片

Input表单写法:

<input type="file" multiple="multiple" accept="image/jpeg" name="newPhoto" value="" id="newPhoto">
multiple选项用于声明是批量上传     accept声明只接收jpg格式的图片,其他格式的文件在选项卡中显示不出来


来自:http://www.cnblogs.com/kissdodog/archive/2012/12/15/2819025.html

一、ajaxFileUpload是一个异步上传文件的jQuery插件。

传一个不知道什么版本的上来,以后不用到处找了。

语法:$.ajaxFileUpload([options])

options参数说明:

1、url            上传处理程序地址。  
2,fileElementId       需要上传的文件域的ID,即<input type="file">的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插件。注意先后顺序,这个不用说了,所有的插件都是这样。

 <script src="jquery-1.7.1.js" type="text/javascript"></script>
 <script src="ajaxfileupload.js" type="text/javascript"></script>
一个例子:
<html>
<head>
    <script src="/jquery-1.7.1.js" type="text/javascript"></script>
    <script src="/ajaxfileupload.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $(":button").click(function () {
                if ($("#file1").val().length > 0) {
                    ajaxFileUpload();
                }
                else {
                    alert("请选择图片");
                }
            })
        })
        function ajaxFileUpload() {
            $.ajaxFileUpload
            (
                {
                    url: '/Home/Upload', //用于文件上传的服务器端请求地址
                    secureuri: false, //一般设置为false
                    fileElementId: 'file1', //文件上传空间的id属性  <input type="file" id="file" name="file" />
                    dataType: 'HTML', //返回值类型 一般设置为json
                    success: function (data, status)  //服务器成功响应处理函数
                    {
                        alert(data);
                        $("#img1").attr("src", data);
                        if (typeof (data.error) != 'undefined') {
                            if (data.error != '') {
                                alert(data.error);
                            } else {
                                alert(data.msg);
                            }
                        }
                    },
                    error: function (data, status, e)//服务器响应失败处理函数
                    {
                        alert(e);
                    }
                }
            )
            return false;
        }
    </script>
</head>
<body>
    <p><input type="file" id="file1" name="file" /></p>
    <input type="button" value="上传" />
    <p><img id="img1" alt="上传成功啦" src="" /></p>
</body>
</html>

我的批量上传:

ajaxFileUpload插件原理其实构建了一个表单form,里面很多file用于上传:最后submit()表单:见下面部分源码

var form = jQuery('<form  action="" method="POST" name="'+ formId + '" id="' + formId
	+ '" enctype="multipart/form-data"></form>');
if (data) {
	for ( var i in data) {
		jQuery('<input type="hidden" name="' + i + '" value="'
			+ data[i] + '" />').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页面的:<img id="loading" src="../images/loading.gif" style="display:none; width: 17px;">
	$("#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<photoList.length;i++){
				var record = "<img src='" + photoList[i].photoName + "' alt='" + photoList[i].id + "' id='headPhoto" + photoList[i].id +
				"' οnclick='selectHeadPhoto(this," + photoList[i].id +")' />";
				additionalRecord += record;
			}
			//加载到该显示的地方
			var headPhotoListTD=$("#headPhotoList",navTab.getCurrentPanel());
			var orignalRecord = headPhotoListTD.html();
			headPhotoListTD.html(orignalRecord + additionalRecord);
		},
		error : function(data, status, e) {
			alertMsg.info(e);
		}
	});
}
SpringMVC框架后台接收:
    @RequestMapping(value = "uploadMultiHeadPhoto.do")
    @ResponseBody
    public AjaxResponseBean uploadMultiHeadPhoto(
    		@ModelAttribute("userInfoBean") UserInfoBean userBean,
            HttpServletRequest request, HttpServletResponse response, ModelMap map) {
UserInfoBean:
private List<MultipartFile> newPhoto;
保存图片到本地并返回List<File>
public static List<File> saveFileList(List<MultipartFile> multipartFiles, String parent, String extend) throws Exception {
	List<File> 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<File>再上传到图片服务器

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('<form  action="" method="POST" name="'
			+ formId + '" id="' + formId
			+ '" enctype="multipart/form-data"></form>');
	//循环遍历构造普通input字段
	if (data) {
		for ( var i in data) {
			jQuery(
					'<input type="hidden" name="' + i + '" value="'
							+ data[i] + '" />').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<photoList.length;i++){
			var record = "<img src='" + photoList[i].photoName + "' alt='" + photoList[i].id + 
			"' id='headPhoto" + photoList[i].id +
			"' οnclick='selectHeadPhoto(this," + photoList[i].id +")' />";
			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('<form  action="" method="POST" name="'
			+ formId + '" id="' + formId
			+ '" enctype="multipart/form-data"></form>');
	//循环遍历构造普通input字段
	if (data) {
		for ( var i in data) {
			jQuery(
					'<input type="hidden" name="' + i + '" value="'
							+ data[i] + '" />').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(
				'<input type="hidden" name="' + i + '" value="'
						+ data[i] + '" />').appendTo(form);
	}
}
这样可以看到问题了,如果data[i]的值中包含双引号" 呢??

那么就会在引号那里被截断

解决方法是替换所有的双引号变成 &quot;

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);
		}
	});
}

省略其他选项卡的处理内容!!!

补充:

之前提到过一个主意事项,就是如果普通表单有双引号的问题,有双引号如果在构建的时候会截断字符串,之前的处理是在每个可能出现的地方都替换了双引号 变成&quot; 

这样就有很多顾虑,而且可能要处理很多字段,倒不如直接在ajaxfileupload.js 中替换来的干脆:

//循环遍历构造普通input字段
if (data) {
	for ( var i in data) {
		//因为拼凑时如果有双引号会截断字符串,于是这里把双引号替换掉
		//2016-01-07
		//author:dhh
		var formData = data[i].replace(/\"/g,"""); //直接在这里处理掉每个字段
		jQuery(
				'<input type="hidden" name="' + i + '" value="'
						+ formData + '" />').appendTo(form);
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值