文件上传三剑客(一)-后台文件存储

文件上传是一个非常常用的组件,遍布在各种系统中,但是好用的上传组件却很难找到(如果有成熟好用的,请不吝赐教)。

最近,做一个系统,恰好修改了三个版本的文件上传,纯web实现,没有flash其他技术。这里整理出来,分享给大家。如果高手有发现问题,尽情喷,也欢迎大家一起探讨。

文件上传中的问题

文件上传本来只是html提供的一个简单组件,直接可以伴随form的提交上传到服务器,但是,我们实际的应用中,经常会遇到一个表单中有许多的文件上传,这个时候如果和表单的属性类字段一起提交,会造成页面长时间没相应,这会带来非常差的用户体验,用户可能会以为服务器无响应,中途刷新页面,造成很多无端的服务器负载。

如何解决这个问题那,一般是这样处理,给文件上传组件添加一个上传按钮,每次单击按钮,就创建一个隐藏的form和一个隐藏iframe,并且form的target指向iframe。把文件上传组件挪动隐藏form中去提交。然后,判断iframe的返回内容。这个也是我这里所说三剑客共同的处理方式。

后台文件存储

本文主要来说明,上传文件在服务器后台也已文件的方式来独立存储的解决方法。文件存储成功后,会返回后台存储的路径信息,作为前台页面的字段值。

下面先把图给上来(有图有真像~_~)

初始时界面:

上传成功后界面:

大概就是上面的效果了,下面开始粘贴代码。

代码

html代码:

<table>
	<tr>
		<th>样例数据</th>
		<td><!-- 只要在一个标签中即可,其他无限制 -->
			<input type="file" name="upfile" />
			<input type="button" classify="exampleDataFile" action="mvc/attachment/add" value="上传" style=""/>
			<input type="button" name="reUpload" value="重新上传" style="display:none;"/>
			<font color="red">*</font>
			<input type="hidden" id="exampleDataFile" name="exampleDataFile" value="" />
		</td>
	</tr>
</table>

JavaScript代码:(补充一句,本来打算clone的形式,但是发现file复制后原来的选择就变空了)

//upload file
if($("input[action]").length>0){
	$('body').append('<div id="hdiv" style="display:none;"></div>');
}
$("input[action]").click(function(){
	//anchor
	var btn=$(this);
	var uploadFile=btn.siblings('input[type=file]');
	//非空判断
	if(!uploadFile.val()){
		alert("请选择要上传的文件,然后点击上传!");
		return false;
	}
	//第一次时候,form和iframe都需要插入
	if($('#f'+btn.attr('classify')).length<=0){
		//拼接出文件提交节点
		var hForm='<form method="post" enctype="multipart/form-data" action="'+btn.attr('action')+'" id="f'+btn.attr('classify')
		+'" name="f'+btn.attr('classify')+'" target="t'+btn.attr('classify')+'">'
		+'<input type="hidden" name="classify" value="'+btn.attr('classify')+'" />'
		+'</form>';
		//拼接出target iframe
		var hFrame='<iframe name="t'+btn.attr('classify')+'" id="t'+btn.attr('classify')+'"></iframe>';
		//添加到文档中
		$('#hdiv').append(hForm).append(hFrame);
	}
		
	//上传组件移动到form下
	uploadFile.appendTo($('#f'+btn.attr('classify')));
	$('#f'+btn.attr('classify')).submit();
		
	//上传成功后标识
	$('#t'+btn.attr('classify')).on('load',function(){
		var result=this.contentWindow.result;
		//把上传组件放回
		uploadFile.insertBefore(btn);
		if(!result){
			alert("上传后台错误,请刷新页面重试,如依旧报错,请联系管理员!");
			return ;
		}
		if(result.result=='success'){
			btn.siblings('input[name="reUpload"]').show();
			btn.siblings('input[type="hidden"]').val(result.filePath);
			//隐藏原来的控件
			btn.hide();
			uploadFile.val('').attr('src','');
			uploadFile.hide();
			//提示信息
			btn.siblings('font').html('已上传,文件路径:'+result.filePath);
		}else{
			alert("上传失败,"+result.message);
		}
	});
});
//reUpload绑定事件
$('input[name="reUpload"]').click(function(){
	var btn=$(this).siblings('input[action]');
	var uploadFile=$(this).siblings('input[type=file]');
		
	uploadFile.val('').show();
	$(this).hide();
	btn.show();
});

后台,我这边是用Java+springMvc,其他的都是类似的,举一反三吧

/**
* 存放目录形式的上传文件
* @param request
* @param classify
* @param upfile
* @return
*/
@RequestMapping(value="/add", method = RequestMethod.POST)
public String add(HttpServletRequest request, @RequestParam("classify") String classify,
			@RequestParam("upfile") MultipartFile upfile){
	String saveName=StringUtils.genUploadFileName(classify, StringUtils.getExtention(upfile.getOriginalFilename()));
	String savePath=request.getSession().getServletContext().getRealPath("/upload")
						+"/"+DateUtil.getCurrent(DateUtil.FULL_DATE_PURE)+"/";
		
//	System.out.println("--->"+upfile.getOriginalFilename());
	//如果目录不存在则创建目录
	File dir=new File(savePath);
	if(!dir.exists()){
		dir.mkdir();
	}
	//保存文件
	try {
		upfile.transferTo(new File(savePath+saveName));
	} catch (IllegalStateException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
		
	//成功后返回内容
	request.setAttribute("result", "success");
	request.setAttribute("message", "上传成功");
	request.setAttribute("filePath", "upload/"+DateUtil.getCurrent(DateUtil.FULL_DATE_PURE)+"/"+saveName);
	return "uploadResult";
}

后台返回结果页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<base href="<%=basePath%>">
<script type="text/javascript">
	result={
			"result": '${result}',
			"message": '${message}',
			"filePath": '${filePath}'
	}
</script>
</head>
<body>

</body>
</html>
上面的代码就javascript比较麻烦,其他的都很容易看懂,javascript的原理其实上面都有说明了,也不可能逐行说明,请自行阅读定制。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值