您的位置:首页 > 其它

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

2016-08-15 16:39 776 查看
当用户上传比较大的文件时,可能需要等待较长的时间,为了增加用户使用的界面友好性,经常在上传文件时使用进度条来显示当前文件上传的进度,本例使用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" onclick="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);
?>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: