ajax上传文件带进度条

此案例使用ajax + springmvc

 1、第一种方式

第一种使用的是ajax formData,这种方式,ie9不支持formData,所以从中方式不使用ie9,(ie10 and ie10+ 没有测试)

html:

<style>
	#prograssbarBorder{
		width:500px;
		height:30px;
		border:1px solid #B2B2B2;
		border-radius:50px 50px 50px 50px;
	}
	#prograssbar{
		width:0px;
		height:30px;
		background:#00D328;
		border-radius:50px 50px 50px 50px;
	}
</style>

<script>
	var xhr;
	if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
		xhr = new XMLHttpRequest();
	} else {// code for IE6, IE5
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}

	$(function() {
		$("#testInfoForm").submit(function() {

			var fileData = document.getElementById('uploadFile').files[0];
			var formData = new FormData();
			xhr.open('post', 'testSaveUpload.do', true);
			xhr.onreadystatechange = function() {
				if (this.readyState == 4) { 
					//0: 请求未初始化
					//1: 服务器连接已建立
					//2: 请求已接收
					//3: 请求处理中
					//4: 请求已完成,且响应已就绪
					document.getElementById('prograssbar').style.width = 100 + '%';
					document.getElementById('precent').innerHTML = Math.floor(100) + '%';
				}
			}
			xhr.upload.onprogress = function(ev) {
				if (ev.lengthComputable) {
					var precent = 100 * ev.loaded / ev.total;
					if(100 == precent){
						document.getElementById('prograssbar').style.width = 99.9 + '%';
						document.getElementById('precent').innerHTML = Math.floor(99.9) + '%';
					}else{
						document.getElementById('prograssbar').style.width = precent + '%';
						document.getElementById('precent').innerHTML = Math.floor(precent) + '%';
					}
					
					
				}
			}
			formData.append('uploadFile', fileData);
			xhr.send(formData);

			return false;
		});
	})
</script>



<div>

	<div id="prograssbarBorder">
        <div id="prograssbar"></div>
    </div>
    <span id="precent"></span><br/>
    
    
	<form id="testInfoForm" enctype="multipart/form-data">
		<div>
			<table>
				<tr>
					<td>上传文件</td>
					<td><input type="file" id="uploadFile" name="uploadFile"
						class="InputStyle" /> *</td>
				</tr>

			</table>
		</div>
		<div>
			<input type="submit" id="saveBtn" />
		</div>
	</form>
</div>

 

 

2、第二种方式

 

第二种方式使用ajaxform,使用ajxasubmit来处理,这种方式支持ie9(仅仅支持文件的上传,不支持进度条显示)同理 ie10 and ie10+ 没有试验。

 

html:

注意:第二中方式需要引入 juqery.form.js

<script type="text/javascript" src="js/jquery.form.js"></script>
<style>
#prograssbarBorder {
	width: 500px;
	height: 30px;
	border: 1px solid #B2B2B2;
	border-radius: 50px 50px 50px 50px;
}

#prograssbar {
	width: 0px;
	height: 30px;
	background: #00D328;
	border-radius: 50px 50px 50px 50px;
}
</style>

<script>
	
	
	function onprogress(ev){
		if (ev.lengthComputable) {
			var precent = 100 * ev.loaded / ev.total;
			if(100 == precent){
				document.getElementById('prograssbar').style.width = 99.9 + '%';
				document.getElementById('precent').innerHTML = Math.floor(99.9) + '%';
			}else{
				document.getElementById('prograssbar').style.width = precent + '%';
				document.getElementById('precent').innerHTML = Math.floor(precent) + '%';
			}
		}
    }
	
	function onreadystatechange(ev){
		if (this.readyState == 4) { 
			//0: 请求未初始化
			//1: 服务器连接已建立
			//2: 请求已接收
			//3: 请求处理中
			//4: 请求已完成,且响应已就绪
			document.getElementById('prograssbar').style.width = 100 + '%';
			document.getElementById('precent').innerHTML = Math.floor(100) + '%';
		}
    }
	
	
	$(function() {
		
		
		/* $('#testInfoForm').ajaxForm(function(){
			 
			 
		}); */
		$("#testInfoForm").submit(function() {
			var option = {
				url : 'testSaveUpload.do',
				type : "post", 
				async : true,  //必须是异步,否则进度条不会显示
				
				success : function(data) {
					var aa = "aaa";
				},
			 	xhr : function(){
	                var xhr = $.ajaxSettings.xhr();
	                if(onprogress && xhr.upload) {
	                    xhr.upload.addEventListener("progress" , onprogress, false);
	                }
	                xhr.addEventListener("readystatechange",onreadystatechange,false);
	                return xhr;
	                
	            },
	            
			};
			
			$("#testInfoForm").ajaxSubmit(option);
			

			return false;
		});
	})
</script>



<div>

	<div  id="prograssbarBorder">
		<div  id="prograssbar"></div>
	</div>
	<span id="precent"></span><br />


	<form id="testInfoForm" enctype="multipart/form-data">
		<div>
			<table>
				<tr>
					<td>上传文件</td>
					<td><input type="file" id="uploadFile" name="uploadFile"
						class="InputStyle" /> *</td>
				</tr>

			</table>
		</div>
		<div>
			<input type="submit" id="saveBtn" />
		</div>
	</form>
</div>

 

 

后台:

@RequestMapping(value="testSaveUpload") 
	public void testSaveUpload(HttpServletRequest request,HttpServletResponse response) throws Exception{
		response.setContentType("text/html");
		MultipartHttpServletRequest multiPartRequest =  (MultipartHttpServletRequest) (request instanceof MultipartHttpServletRequest ? request : null) ;
		MultipartFile uploadFile = multiPartRequest.getFile("uploadFile");
		String originalFilename = uploadFile.getOriginalFilename();
		String subfix = originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length());
		File filePaht = new File("D:\\TestM\\Exam\\"+UUID.randomUUID().toString()+subfix);
		uploadFile.transferTo(filePaht);
		response.setStatus(HttpServletResponse.SC_OK);
		response.getOutputStream().println("aaa");
	}
	

 

 

 3、第三种方式

 第三种方式,使用前台不断给后台发送请求,后台利用线程,将已经读取的文件返回给前台这种方式,兼容ie9。同样用到了 ajaxform,使用ajxasubmit提交。需要引入 juqery.form.js

html:

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ include file="/common/common.jsp"%>
<%@ include file="/common/tips.jsp"%>

<script type="text/javascript" src="js/jquery.form.js"></script>
<style>
#prograssbarBorder {
	width: 500px;
	height: 30px;
	border: 1px solid #B2B2B2;
	border-radius: 50px 50px 50px 50px;
}

#prograssbar {
	width: 0px;
	height: 30px;
	background: #00D328;
	border-radius: 50px 50px 50px 50px;
}
</style>

<script>
	
	
	$(function() {
		
		$("#testInfoForm").submit(function() {
			
			var option = {
				url : 'testSaveUpload.do',
				type : "post", 
				success : function(data) {
					// requestStatus+",,,"+threadId+",,,"threadStatus
					var requestStatus = data.split(",,,")[0];
					var currentThreadId = data.split(",,,")[1];
					var threadStatus = data.split(",,,")[2];
					var totalSize = data.split(",,,")[3];
					var readSize = data.split(",,,")[4];
					if(requestStatus == 'running'){//未完成,正在运行
						$("#threadId").val(currentThreadId);
						var precent = 100 * readSize / totalSize;
						document.getElementById('prograssbar').style.width = precent + '%';
						document.getElementById('precent').innerHTML = Math.floor(precent) + '%';
					}else if(requestStatus == 'success'){ //上传完成,成功
						$("#threadId").val("");
						clearInterval(myInterval);
						document.getElementById('prograssbar').style.width = 100 + '%';
						document.getElementById('precent').innerHTML = Math.floor(100) + '%'; 
					}else if(requestStatus == 'failed'){ //上传失败
						$("#threadId").val("");
						clearInterval(myInterval);
					}else{
						$("#threadId").val("");
						clearInterval(myInterval);
					}
				},
				error : function (){
					$("#threadId").val("");
					clearInterval(myInterval);
				},
	            
			};
			
			
			var myInterval =setInterval(function(){
				var threadId = $("#threadId").val();
				$("#testInfoForm").ajaxSubmit(option);
			},500);
	
			return false;
		});
			
			
			
		
		
		
		
		
		
		
		
		
		
		
	})
</script>



<div>

	<div  id="prograssbarBorder">
		<div  id="prograssbar"></div>
	</div>
	<span id="precent"></span><br />

	
	<form id="testInfoForm" enctype="multipart/form-data">
	
		<input type="hidden" id="threadId" name="threadId" /> 
		<div>
			<table>
				<tr>
					<td>上传文件</td>
					<td><input type="file" id="uploadFile" name="uploadFile"
						class="InputStyle" /> *</td>
				</tr>

			</table>
		</div>
		<div>
			<input type="submit" value="提交" id="saveBtn" />
		</div>
	</form>
</div>
 

 

 

后台:

 

 

@RequestMapping(value="testSaveUpload") 
	public void testSaveUpload(HttpServletRequest request,HttpServletResponse response,String threadId) throws Exception{
		MultipartHttpServletRequest multiPartRequest =  (MultipartHttpServletRequest) (request instanceof MultipartHttpServletRequest ? request : null) ;
		MultipartFile uploadFile = multiPartRequest.getFile("uploadFile");
		String originalFilename = uploadFile.getOriginalFilename();
		String subfix = originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length());
	
		InputStream input = uploadFile.getInputStream();
		//总大小
		long totleSize = uploadFile.getSize();
		System.out.println("总大小:---》"+totleSize);
		
		long readSum = 0l;
		if(StringUtils.isNotBlank(threadId)){ //当前线程正在运行
			ReadFileThread readFileThread = (ReadFileThread) ConstantMap.constantMap.get(threadId);
			//获取已读大小
			long readSize = readFileThread.getReadSum();
			//线程状态
			String threadStatus = readFileThread.getThreadStatus();
			if("completed".equals(threadStatus)){ //线程已经运行完毕
				ConstantMap.constantMap.remove(threadId);
				response.getOutputStream().println("success,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}else if("error".equals(threadStatus)){ //出错
				ConstantMap.constantMap.remove(threadId);
				response.getOutputStream().println("failed,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}else if("uncompleted".equals(threadStatus)){ //未完成
				response.getOutputStream().println("running,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}
			return ;
		}else{ // 一个新的请求
			File filePaht = new File("D:\\TestM\\Exam\\"+UUID.randomUUID().toString()+subfix);
			//文件夹不存在就创建
			if(!filePaht.getParentFile().exists()){
				filePaht.getParentFile().mkdirs();
			}
			FileOutputStream output = new FileOutputStream(filePaht);
			threadId = UUID.randomUUID().toString();
			
			//创建一个新的线程
			ReadFileThread readFileThread = new ReadFileThread(input, output,readSum);
			Thread thread = new Thread(readFileThread);
			thread.start();
			//获取已读大小
			long readSize = readFileThread.getReadSum();
			//线程状态
			String threadStatus = readFileThread.getThreadStatus();
			if("completed".equals(threadStatus)){ //线程已经运行完毕
				ConstantMap.constantMap.remove(threadId);
				System.out.println("end");
				response.getOutputStream().println("success,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}else if("error".equals(threadStatus)){ //出错
				ConstantMap.constantMap.remove(threadId);
				response.getOutputStream().println("failed,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}else if("uncompleted".equals(threadStatus)){ //未完成
				ConstantMap.constantMap.put(threadId, readFileThread);
				response.getOutputStream().println("running,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}
		}
		return ;
		
	}
 

 

 

class ReadFileThread implements Runnable{
		
		InputStream input;
		FileOutputStream output;
		String threadStatus = "uncompleted";
		long readSum;
		
		public String getThreadStatus() {
			return threadStatus;
		}
		public void setThreadStatus(String threadStatus) {
			this.threadStatus = threadStatus;
		}
		
		public Long getReadSum() {
			return readSum;
		}
		
		public ReadFileThread(InputStream input,FileOutputStream output, Long readSum) {
			this.input = input;
			this.output = output;
			this.readSum = readSum;
		}
		@Override
		public void run() {
			int readLength = 0;
			byte[] buffer = new byte[1444]; 
			try {
				while ( (readLength = input.read(buffer)) != -1) { 
					readSum += readLength; 
					System.out.println("已读大小:--》"+readSum);
					output.write(buffer, 0, readLength); 
				} 
			} catch (Exception e) {//出错
				this.setThreadStatus("error");
			}finally{
				try {//完成,成功
					this.setThreadStatus("completed");
					if(null != output){
						output.close();
					}
					if(null != output){
						input.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		}
		
	}
 

 

package com.exam.bean.common;

import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ConstantMap {
	//此处使用 hashtable ,防止并发问题
	public static Hashtable<String, Object> constantMap = new Hashtable<>();
	
	public static void setConstantMap(String key,Object value){
		if(constantMap.containsKey(key)){
			constantMap.remove(key);
			constantMap.put(key, value);
		}else{
			constantMap.put(key, value);
		}
	}
	
	public static Object getConstantMap(String key){
		Pattern pattern = Pattern.compile("\r\n");
		Matcher matcher = pattern.matcher(key);
		key = matcher.replaceAll("");
		if(constantMap.containsKey(key)){
			return constantMap.get(key);
		}
		return null;
	}
	
	public static Object removeConstantMap(String key){
		if(constantMap.containsKey(key)){
			return constantMap.remove(key);
		}
		return null;
	}
	
	
	
	
}

 

 

 

 

 

 

 

 

运行效果如下:



 

 

 

 另外附上:juqery.form.js

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现Ajax上传文件并显示进度条,您可以使用FormData对象和XMLHttpRequest对象。以下是一个简单的示例代码: HTML代码: ``` <form id="file-upload-form"> <input type="file" name="file"> <button type="submit">上传文件</button> </form> <div id="progress-bar"></div> ``` JavaScript代码: ``` var form = document.getElementById('file-upload-form'); var progressBar = document.getElementById('progress-bar'); form.addEventListener('submit', function(e) { e.preventDefault(); var formData = new FormData(this); var xhr = new XMLHttpRequest(); // 监听上传进度 xhr.upload.addEventListener('progress', function(e) { if (e.lengthComputable) { var percentComplete = (e.loaded / e.total) * 100; progressBar.style.width = percentComplete + '%'; } }, false); // 完成上传 xhr.addEventListener('load', function() { progressBar.innerHTML = '上传完成!'; }, false); // 处理上传错误 xhr.addEventListener('error', function() { progressBar.innerHTML = '上传失败。'; }, false); // 发送上传请求 xhr.open('POST', 'upload.php'); xhr.send(formData); }); ``` 在这个示例中,我们首先获取了表单和进度条元素。然后,我们监听了表单的提交事件,阻止了默认的表单提交行为。接着,创建了FormData对象来包含上传的文件数据,并创建了XMLHttpRequest对象。我们给XMLHttpRequest对象添加了一个上传进度事件监听器,当上传进度发生变化时,更新进度条的宽度。接着,我们添加了一个成功上传完成的事件监听器和一个上传错误的监听器。最后,我们打开了一个POST请求,并将FormData对象作为参数发送到服务器。 请注意,这只是一个基本的示例,您需要根据自己的需求进行修改。同时,要确保服务器端也能够处理Ajax上传请求,并返回正确的响应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值