文章地址 http://leethrun.cn/index.php/archives/8/
基于webuploader的分片上传 ,需要引入jquery,下载webuploader,
前端部分
<html>
<head>
<link rel="stylesheet" href="webuploader/webuploader.css">
</head>
<body>
<button type="button" id="upload" class="layui-btn" style="background-color: #00aec3;margin-right: 15px;" >上传</button>
</body>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="webuploader/webuploader.min.js"></script>
<script>
//上传控件
uploadBig('upload','zip,rar,7z,tar',{
id: '',
type: 'upload_file',
} ,(res)=>{
//todo 上传完成回调
console.log('上传完成',res);
},(percent)=>{
//todo 上传中回调
console.log(percent);
})
/*
* 大文件分片上传
* @param btn 绑定上传按钮 id
* @param ext 上传文件后缀限制 英文逗号分隔
* @param formData 额外参数
* @param callback 回调函数 function
* @param progress 上传过程回调函数 function
*
*/
function uploadBig(btn,ext,formData,callback,progress){
var arr = ext.split(',');
var mimeTypes = '';
for(var ai=0;ai<arr.length;ai++){
mimeTypes += '.'+arr[ai]+','
}
mimeTypes = mimeTypes.substring(0,mimeTypes.length-1);
let uploader = new WebUploader.Uploader({
// swf文件路径
// swf: 'webuploader/Uploader.swf',
// 文件接收服务端。
server: 'uploader.php',
auto:true,
// 选择文件的按钮。可选。
// 内部根据当前运行是创建,可能是input元素,也可能是flash.
pick: '#'+btn,
// 分片上传。
chunked: true,
threads:1,//并发上传数
chunkSize: 2 * 1024 * 1024, //分片文件大小, 2M
// 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
resize: false,
accept: {
title:'',
extensions:ext,
mimeTypes:mimeTypes
},
formData: formData
});
// //开始上传
// $('#ctlBtn').click(function () {
// uploader.upload();
// });
let $list = $('#upload_big_list');
// 当有文件被添加进队列的时候
uploader.on( 'fileQueued', function( file ) {
$list.append( '<div id="' + file.id + '" class="item">' +
// '<h4 class="info">' + file.name + '</h4>' +
// '<p class="state"></p>' +
'</div>' );
uploader.upload();
});
// 文件上传过程中创建进度条实时显示。
uploader.on( 'uploadProgress', function( file, percentage) {
if(typeof progress == 'function'){
progress(percentage);
}
});
uploader.on( 'uploadSuccess', function( file, response ) {
if (response.status == 1) {
callback(response);
}
});
uploader.on("error", function (type) {
if (type == "Q_TYPE_DENIED") {
alert("上传文件类型错误!");
}
else if(type == 'F_DUPLICATE'){
alert("上传文件重复");
}
// else if (type == "Q_EXCEED_SIZE_LIMIT") {
// alert("文件大小不能超过2M");
// }
else {
alert("上传出错,请联系管理员。error: "+type);
}
});
}
</script>
</html>
后台 uploader.php
<?php
header("Content-type: text/html; charset=utf-8");
header('Access-Control-Allow-Origin:*');
//储存分片
//获取文件后缀名
$ext_name = substr(strrchr($_REQUEST['name'], '.'), 1);
//随机生成保存的文件名
$file_name = GetRandStr(10).".$ext_name";
//分片保存目录
$request_name = $_REQUEST['name'];
$tmp_dir = 'upload/chunk_tmp/' .$request_name . '/';
//文件保存目录
$target_file = "upload/;
if (! is_dir($tmp_dir)) {
mkdir($tmp_dir, 0777, true);
}
if(!isset($_REQUEST['chunk'])){
$chunk = '0';
$chunks = '1';
}else{
$chunk = $_REQUEST['chunk'];
$chunks = $_REQUEST['chunks'];
}
move_uploaded_file($_FILES['file']['tmp_name'], $tmp_dir . $chunk);
//合并分片
if ($chunk == $chunks - 1) { //最后一个分片
if (! is_dir($target_file)) {
mkdir($target_file, 0777, true);
}
$target_file .= $file_name;
$handle = fopen($target_file, 'x+');
for ($i=0; $i<$chunks; $i++) {
fwrite($handle, @file_get_contents($tmp_dir . $i));
}
fclose($handle);
//删除分片文件
// for ($i=0; $i<$_REQUEST['chunks']; $i++) {
// @unlink($tmp_dir . $i);
// }
// rmdir($tmp_dir);
$msg = [
'$_FILES' => json_encode($_FILES),
'$_REQUEST' => json_encode($_REQUEST),
];
echo json_encode(['status' => 1,'file_path'=>$target_file,'file_name'=>$file_name]);exit;
}else{
$target_file = '';
}
$msg = [
'$_FILES' => json_encode($_FILES),
'$_REQUEST' => json_encode($_REQUEST),
];
echo json_encode(['status' => 1, 'msg' => json_encode($msg),'file_path'=>$target_file,'file_name'=>$file_name]);exit;
function GetRandStr ($length){
$str='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$len=strlen($str)-1;
$randstr='';
for($i=0;$i<$length;$i++){
$num=mt_rand(0,$len);
$randstr .= $str[$num];
}
return $randstr;
}