大致思路:
1.获取文件信息
2.通过‘’文件对象‘’中的slice方法对文件进行不断切割
3.将切割的二进制信息“装载”入FormData对象然后通过XMLHttpRequest对象发送请求
4.在服务端将不断送过来的二进制信息进行拼接
下面代码是参考十八哥(燕十八)的公益教学视频写出来的,并在原有基础上加了点改进。
<script>
var clock = null;
var xhr = new XMLHttpRequest();
function fire()
{
var data = new FormData();
createDiv();
data.append('fName', document.getElementsByName('part')[0].files[0].name);
send(data);
clock = window.setInterval(upFile, 1000);
}
var upFile = (function(){
var fInstro = null;
const LENGTH = 10 * 1024 * 1024;
var fd = null;
var blob = null;
var sta = 0;
var end = LENGTH;
var sending = false;
var fName = '';
return (function(){
if (true == sending)
{
return;
}
fInstro = document.getElementsByName('part')[0].files[0];
fName = fInstro.name;
if (sta > fInstro.size)
{
var body = document.getElementsByTagName('body')[0];
var tl = document.getElementById('tl');
tl.removeChild(ld);
body.removeChild(tl);
clearInterval(clock);
sta = 0;
end = LENGTH;
return;
}
fd = new FormData();
blob = fInstro.slice(sta, end);
fd.append('part', blob);
fd.append('fName', fName);
send(fd);
xhr.upload.onprogress = function (ev)
{
if (sta > fInstro.size)
{
ld.style.width = 100 + '%';
}
else
{
ld.style.width = sta/fInstro.size * 100 + '%';
}
}
sta = end;
end = sta + LENGTH;
sending = false;
});
})();
function send(fd)
{
xhr.open('POST', './01.php', true);
xhr.send(fd);
return true;
}
function createDiv()
{
var tl = document.createElement("div");
var ld = document.createElement("div");
tl.setAttribute('id', 'tl');
ld.setAttribute('id', 'ld');
tl.appendChild(ld);
document.getElementsByTagName('body')[0].appendChild(tl);
tl.style.width = 500 + 'px';
tl.style.height = 30 + 'px';
tl.style.border = '1' + 'px' + ' ' + 'solid' + ' ' + 'green';
ld.style.width = 0 + '%';
ld.style.height = 30 + 'px';
ld.style.background = 'green';
}
</script>
以下是后端php处理代码
<?php
$fName = iconv('utf-8', 'gbk', $_POST['fName']);
if (!file_exists('./upload/'.$fName))
{
file_put_contents('./upload/'.$fName, '');
}
else
{
file_put_contents('./upload/'.$fName, file_get_contents($_FILES['part']['tmp_name']), FILE_APPEND);
}
因为编码不同,所以当路径或文件名有中文字符时,函数 file_put_contents会出错,所以需要用iconv转换一下字符编码。
代码可能有点冗余,初次学ajax还请多多包涵!!
1.设置每次切割的大小不要超过php.ini中post_max_size设置的大小否则或出错。
2.另外值得一提的是FormData对象大小有限制,所以需要不断new出新的对象,否则也会出错。