ajax实现文件分块上传,ajax xhr 大文件分块上传前端和后端代码

【HTML部分】

选择文件

开始上传

支持上传文件格式:PDF,PSD,AI,CDR

当前选择:

上传文件:

【Javascript部分】

var selectfiles_button =document.getElementById("c-files");

var postfiles_button =document.getElementById("postfiles");

var file_info_button =document.getElementById("file_info");

var step_line_button =document.getElementById('step_line');

var server_info_button =document.getElementById('server_info');

//上传文件侦测侦测

selectfiles_button.addEventListener("change",(e)=>{

//console.log(e.target.files[0]);

step_line_button.innerHTML ='';

file_info_button.innerHTML ='';

var reader = new FileReader();

var file =e.target.files[0];

//reader.readAsDataURL(e.target.files[0]);

reader.readAsDataURL(file);

reader.οnlοadstart= function(){

console.log(reader.result);

//selectfiles_button.setAttribute("value",reader.result);

file_info_button.innerHTML= file.name;

}

})

//上传POST

postfiles_button.addEventListener("click", function(){

// 文件对象

var file = selectfiles_button.files[0];

// 分块的大小 默认4M

var block = 1024 * 1024 * 10;

// 文件大小

var fileSize = file.size;

// 总的分块数

var totalCount = Math.ceil(fileSize / block);

var start = 0,

end = 0;

// 原文件名

var fileName = file.name;

// 生成随机的前缀

var prfix = Math.random();

//返回服务器文件地址

var server_url ='1';

var init_b =0;

for(var num = 0; num

//块数据

start = num * block;

end = start + block;

blockFile = file.slice(start, end);

// 组装 FormData() 对象

var formData = new FormData();

formData.append('file', blockFile);

formData.append('num', num);

formData.append('fileName', fileName);

formData.append('prfix', prfix);

formData.append('totalCount', totalCount);

//AJAX请求

var xhr =new XMLHttpRequest(num);

//采用同步的方式

xhr.open('post','user.php?act=blob',false);

//获取进度条对象

var jdt=document.querySelector('#step_line');

//返回状态

xhr.onload = function(dd) {

//console.log('ff_'+num);

//console.log(jdt);

if (xhr.readyState === 4) {

if (xhr.status === 200) {

//console.log(this.response);

//刷新进度条

var curr =num+1;

var total =totalCount;

var percent = Math.ceil((curr/total)*100);

var len = percent * 300 /100;

jdt.innerHTML=percent+'%';

jdt.setAttribute("style","width:"+len+"px;background:green;border-radius: 10px;");

//赋值

var result =JSON.parse(this.response);

//console.log(result);

if(result.code==1){

if(typeof(result.url)=='undefined'||result.url==''||result.url==null){

server_info_button.innerHTML='';

}else{

server_info_button.innerHTML=result.url;

}

}else{

//失败要回滚 删除临时缓存

}

} else {

console.error(xhr.statusText);

}

}

};

//设置请求超时的时间

//xhr.timeout = 3000;

init_b =1;

//发送请求

xhr.send(formData);

}

});

【PHP后端】/**分块上传**/

function action_blob(){

//设置json格式

header('content-type:application/json;charset=utf-8');

// 接收 post 和FILES参数

$data = $_POST;

$file = $_FILES;

if(!$file['file']){

exit(json_encode(['code'=>0,'msg'=>'文件不存在']));

}

//创建目录

$dir=ROOT_PATH .'data/block/'; //块临时目录

$save_dir=ROOT_PATH .'data/printfile/'; //最终目录

if(!is_dir($dir)){

mkdir($dir,0777);

}

if(!is_dir($save_dir)){

mkdir($save_dir,0777);

}

// 分块文件位置

$block_path =$dir. $data['prfix']. '_';

//临时保存分块

$save_key =$dir.$data['prfix'].'_' . $data['num'];

move_uploaded_file($file['file']['tmp_name'],$save_key );

$done = 0;

$file_url='';

// 判断文件是否上传完成

if ($data['num'] == ($data['totalCount'] - 1)) {

$ext = pathinfo($data['fileName'], PATHINFO_EXTENSION);

$newFileName = $data['prfix'] . '.' . $ext;

// 合并文件 注意file_put_contents 添加FILE_APPEND 避免替换数据

for($i = 0; $i < $data['totalCount']; $i++) {

file_put_contents($save_dir. $newFileName, file_get_contents($block_path.$i),FILE_APPEND);

}

// 合并完成后删除分块文件

for($i = 0; $i < $data['totalCount']; $i++) {

unlink($dir. $data['prfix'] . '_' . $i);

}

$done = 1;

$file_url=$save_dir.$newFileName;

//上传完成后返回

exit(json_encode(['code'=>1,'msg'=>'文件上传成功','url'=>$file_url]));

}

//返回状态

exit(json_encode(['code'=>1,'msg'=>'分块上传成功']));

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值