利用Ajax FormData实现无刷新带进度条文件上传

8 篇文章 0 订阅

当用户上传比较大的文件时,可能需要等待较长的时间,为了增加用户使用的界面友好性,经常在上传文件时使用进度条来显示当前文件上传的进度,本例使用FormData。XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件。

首先修改php.ini配置文件开放大附件上传限制,重启apache

; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; http://php.net/post-max-size
post_max_size = 200M
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 200M

1.浏览器显示界面设计

<!DOCUMENT html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http
://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
	<title>商品列表</title>
	<script type="text/javascript">
		//通过页面加载事件实现分页数据获取
		function sub(){
			//Ajax对象
			var obj = new XMLHttpRequest();
			//接收响应的信息
			obj.onreadystatechange =function(){
				if (obj.readyState == 4 && obj.status ==200 ) {
					document.getElementById('con').innerHTML = obj.responseText;
				}
			}
			//onproess属性通过主流浏览器的"事件对象evt"感知当前附件上传情况,该事件每0.1s执行一次
			obj.upload.onprogress = function(evt){
				//上传附件大小的百分比
				//其中evt.total表示附件中大小。evt.loaded表示已经上传附件的大小
				var per = Math.floor((evt.loaded/evt.total)*100)+"%";
				//当上传文件时,显示进度条
				document.getElementById('parent').style.display ='block';
				//通过上传百分比设置进度条样式的宽度
				document.getElementById('son').style.width = per;
				//在进度条上显示上传的进行
				document.getElementById('son').innerHTML = per;
			}
			//通过FormData收集零散的上传文件信息
			var fm = document.getElementById('userfile3').files[0];
			//alert("fm:"+fm);
			var fd = new FormData();
			fd.append('userfile',fm);
			obj.open('post','./upData.php');
			obj.send(fd);
		}
	</script>
	<style type="text/css">
	#parent{width: 200px;height: 20px;border:2px solid gray;background:lightgray;display: none}
	#son{width: 0;height: 100%;background: lightgreen;text-align: center;}
	</style>
</head>
<body>
	<h2>Ajax实现文件上传进度条</h2>
	<div id = "parent"> 
		<div id="son">
		</div>
	</div>
	<p id="con"></p> 
	<input type="file" name="userfile" id="userfile3"><br/><br/>
	<input type="button" οnclick="sub()" value="文件上传">
</body>
</html>
2.php处理上传文件信息upData.php
<?php
	//判断文件上传到临时目录是否出错,如果出错则输出错误信息并退出
	if($_FILES['userfile']['error']>0)
	{
		$error_msg = '上传错误:';
		switch($_FILES['userfile']['error'])
		{
			case 1:
				$error_msg.="文件大小超出了php.ini中upload_max_filesize的值";
			break;
			case 2:
				$error_msg.="文件大小超出了表单中max_file_size选项指定的值";
			break;
			case 3:
				$error_msg.="文件只有部分被上传";
			break;
			case 4:
				$error_msg.="没有文件被上传";
			break;
			case 6:
				$error_msg.="找不到临时文件";
			break;
			case 7:
				$error_msg.="文件写入失败";
			break;
			default:
				$error_msg.="位置错误";
			break;
		}
		echo $error_msg;
		exit;
	}
	//上传到临时目录成功,将其复制到脚本文件所在的uploads文件夹中。
	
	if(is_uploaded_file($_FILES['userfile']['tmp_name']))
	{
		if(!($file=iconv('UTF-8','GB2312',$_FILES['userfile']['name'])))
		{
			echo '转换失败';
			exit;
		}
		$destination = 'uploads/'.$file;
		if(move_uploaded_file($_FILES['userfile']['tmp_name'],$destination))
		{
			echo "upload success";
			//跳转到用户首页
			header('refresh:3;url=form.html');
		}
	}

?>

3.运行结果


总结:<form enctype="multipart/form-data">

<input type="file">

服务器端:$_FILES接收附件信息(name、error、size、type、tmp_name)

error:

0--------->ok

1--------->大小超过php.ini限制

2--------->大小超过了MAX_FILE_SIZE表单域限制

3--------->文件只上传了一部分

4--------->文件没有上传

move_uploaded_file(附件临时路径名,真实附件路径名)

收集附件信息:

dom方式只可以收集普通的表单域信息,并且浏览器由于安全方面的限制也禁止通过javascript语言操作本地文件.

使用FormData既可以实现表单信息的收集,也可以实现文件信息的收集。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"  >
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
	<title>ajax</title>
	<style type="text/css">
	</style>
	<script type="text/javascript">
		window.onload = init;
		 function init(){
		 	var fm = document.getElementsByTagName('form')[0];
			fm.onsubmit = function(){
				//收集表单信息
				//ajax负责把收集好的信息传递给服务器
				var fd = new FormData(fm);

				var xhr = new XMLHttpRequest();
				xhr.onreadystatechange = function(){
					if(xhr.readyState==4){
						alert(xhr.responseText);
					}
				}
				xhr.open('post','./04.php');
				//使用FormData无需设置header头
				//xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				xhr.send(fd);
				//阻止浏览器默认动作 跳转
				return false;
			}
		}
	</script>
</head>
<body>
<h2>Ajax无刷新收集表单并提交表单</h2>
<form>
	<p>用户名:<input type="text" name="username" id="username"></input></p>
	<p>密码:<input type="password" name="userpwd" id="userpwd"></input></p>
	<p>邮箱:<input type="text" name = "useremail" id="useremail"></input></p>
	<p>头像上传:<input type="file" name="userfile"></input></p>
	<p><input type="submit" value="注册"></input></p>
</form>
</body>	
</html>

./04.php

<?php
//接收get方式传递过来的用户名信息,并做数据校验
print_r($_POST);
echo "file";
print_r($_FILES);
?>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值