Ajax大文件切割上传
Sep 7, 2014
对于我们这波电脑控的90后来说,在网上上传照片、压缩文件、视频等等已经是常见的事了。但是,不知道大家有没有疑问,就是说我们可以上传只有几兆的图片、稍大一点的十几兆的打包文件,甚至于几十兆或者几百兆的文件,更有甚者是上G的大视频文件,是不是可以无限制的上传更大的数据文件呢?!
答案正如你所想的,肯定是否定的嘛。服务器端怎么可以任由你上传无限大的文件呢,一般服务器端都会设置最大上传文件的大小来进行限制,那么当我们需要上传大文件时该如何实现呢?
这里我们使用的是打文件切割技术来进行分块上传,然后在服务器端接受切割后的小文件进行一系列的合并,最后将打文件成功上传到服务器端,这就是其基本原理。
###思路:
- 设置文件切割大小,这里假设为10M
- 使用定时器进行函数调用
- 判断文件是否截取完毕
废话不多说,直接上代码:
js代码
<script type="text/javascript" charset="utf-8">
//全局对象
var xhr = new XMLHttpRequest();
var clock = null;
var mov = null;
//事件监控函数
function fire () {
mov = document.getElementsByTagName('input')[0].files[0];
clock = window.setInterval(sendfile, 1000);
}
//闭包计数器
var sendfile = function () {
const LENGTH = 10 * 1024 * 1024; //10M
var sta = 0; //切割开始位置
var end = sta + LENGTH; //切割结束位置
var sending = false; //标志正在上传
var blob = null; //用来存储切割数据
var fd = null; //表单对象声明
//返回一个匿名函数
return (function () {
if (sending == true) {
return;
}
//如果sta > mov.size ,就结束
if (sta > mov.size) {
window.clearInterval(clock);
return;
}
blob = mov.slice(sta, end); //切割
fd = new FormData(); //定义表单对象
fd.append('part', blob);
up(fd); //开始上传
sta = end;
end = end + LENGTH;
sending = false; //上传完毕
percent = 100 * end / mov.size;
if (percent > 100) {
percent = 100;
}
document.getElementById('bar').style.width = percent + '%';
document.getElementById('bar').innerHTML = parseInt(percent) + '%';
});
}();
//上传函数
function up (fd) {
xhr.open('POST', './upload.php', false); //同步传输
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(fd);
}
</script>
html代码
<head>
<style type="text/css">
#one {
width : 500px;
height :20px;
border = 1px solid green;
}
#bar {
width : 0%;
height : 100%;
background-color:green;
}
</style>
</head>
<body>
<input type="file" name="pic" value="" id="pic" onchange="fire();"><br />
<div id="one"><div id="bar"></div></div>
</body>
服务器端代码
<?php
/**
* 测试代码
* 服务器接收文件并合并
* */
if (isset($_FILES['part']['tmp_name'])) {
if (!file_exists('./upload/up.wmv')) {
move_upload_file($_FILES['part']['tmp_name'], './upload/up.wmv');
} else {
file_put_contents('./upload/up.wmv', file_get_contents($_FILES['part']['tmp_name']), FILE_APPEND);
}
}
?>
###知识点:
1、闭包处理
2、匿名函数
3、Blob对象的slice方法
4、表单FormData对象使用
5、XMLHttpRequest对象(Ajax引擎对象)
6、js的window.setInterval方法
注意:
有时间的话,比较下setTimeout方法和setInterval方法的区别与适用范围?
(END)