推薦的分塊大小是2M-5M,具體size根據產品中文件上傳的大小分佈來定。若是上傳的文件大部分是500M以上,很大的文件,建議是5M, 若是相對較小,推薦2M。javascript
節省流量,避免上傳重複的分塊。php
減小用戶等待時間。css
可恢復的上傳。出現中斷,就算瀏覽器刷新或者是換了臺電腦也能恢復到上次中斷的位置。html
如下代碼上傳音頻有點問題,上傳進度沒有作,往後閒時補上。html5
(function ($, global, doc) { var form = doc.forms["upload"]; // Upload類 function Upload (file) { this.file = file; this.fileInfo = { fileName: this.file.name, fileType: this.file.type, fileSize: this.file.size }; this.reader = new FileReader(); // 開始讀取指定的Blob對象或File對象中的內容. 當讀取操做完成時,readyState屬性的值會成爲DONE,若是設置了onloadend事件處理程序,則調用之.同時,result屬性中將包含所讀取文件的原始二進制數據. this.reader.readAsBinaryString(this.file); // 塊大小默認爲4MB this.opts = { chunkSize: 4 * 1024 * 1024, chunkIndex: 0 }; $.extend(this.opts, { chunkCount: Math.ceil(this.fileInfo.fileSize / this.opts.chunkSize) }); this.bindEvent(); return this; }; Upload.prototype = { bindEvent: function () { var self = this; self.reader.onloadstart = function () { self.uploadChunk(); }; return self; }, uploadFinish: function (data) { var self = this; var previewStr = ''; switch (self.fileInfo.fileType.substring(0, self.fileInfo.fileType.indexOf('/'))) { case 'image': previewStr = '<img src="' + ('upload/' + data.url) + '">'; $('.preview').html(previewStr); break; case 'audio': previewStr = '<audio src="' + ('upload/' + data.url) + '" controls="controls"></audio>'; break; default: $('.preview').html(previewStr); } return self; }, updateProcess: function () { return this; }, uploadChunkAfter: function (data) { var self = this; self.opts.chunkIndex++; if (self.opts.chunkIndex < self.opts.chunkCount) { self.uploadChunk(); } else { self.uploadFinish(data); } updateProcess(); return self; }, uploadChunk: function () { var fData = new FormData(); var self = this; fData.append("file", self.file.slice(self.opts.chunkIndex * self.opts.chunkSize, self.opts.chunkSize * (self.opts.chunkIndex + 1))); fData.append("fileName", self.fileInfo.fileName); fData.append("fileSize", self.fileInfo.fileSize); fData.append("fileType", self.fileInfo.fileType); fData.append("chunkCount", self.opts.chunkCount); fData.append("chunkIndex", self.opts.chunkIndex); fData.append("trueName", self.fileInfo.fileName.substring(0, self.fileInfo.fileName.lastIndexOf('.'))); $.ajax({ url: 'controller/upload.php', type: 'POST', data: fData, processData: false, contentType: false, cache: false, dataType: "json", success: function (data) { self.uploadChunkAfter(data); } }); return self; }, util: function () { return { // 字節轉換成對應的單位 bytesTosize: function (data) { var unit = ["Bytes", "KB", "MB", "GB"]; var i = parseInt(Math.log(data) / Math.log(1024)); return (data / Math.pow(1024, i)).toFixed(1) + " " + unit[i]; }, // 秒轉換成對應的時間 secondsTotime: function (sec) { var h = Math.floor(sec / 3600), m = Math.floor((sec - h * 3600) / 60), s = Math.floor(sec - h * 3600 - m * 60); if(h < 10) h = "0" + h; if(m < 10) m = "0" + m; if(s < 10) s = "0" + s; return h + ":" + m + ":" + s; } } } }; $('#submit').on('click', function () { var File = new Upload(form["file"].files[0]); return false; }); })(jQuery, window, document);
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>分塊上傳</title> </head> <body> <form name="upload" action="" enctype="multipart/form-data" method="post"> <input type="file" id="file" name="file"> <input type="button" id="submit" value="提交"> </form> <div class="preview"></div> <script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script> <script src="js/upload.js"></script> </body> </html>
<?php $fsize = $_POST['fileSize']; $findex =$_POST['chunkIndex']; $ftotal =$_POST['chunkCount']; $ftype = $_POST['fileType']; $fdata = $_FILES['file']; $fname = mb_convert_encoding($_POST['fileName'],"gbk","utf-8"); $truename = mb_convert_encoding($_POST['trueName'],"gbk","utf-8"); $path = "../"; $dir = $path."upload/".$truename."-".$fsize; $save = $dir."/".$fname; if(!is_dir($dir)) { mkdir($dir); chmod($dir,0777); } //讀取臨時文件內容 $temp = fopen($fdata["tmp_name"],"r+"); $filedata = fread($temp,filesize($fdata["tmp_name"])); //將分段內容存放到新建的臨時文件裏面 if(file_exists($dir."/".$findex.".tmp")) unlink($dir."/".$findex.".tmp"); $tempFile = fopen($dir."/".$findex.".tmp","w+"); fwrite($tempFile,$filedata); fclose($tempFile); fclose($temp); if($findex+1 == $ftotal) { if(file_exists($save)) @unlink($save); //循環讀取臨時文件並將其合併置入新文件裏面 for($i=0;$i<$ftotal;$i++) { $readData = fopen($dir."/".$i.".tmp","r+"); $writeData = fread($readData,filesize($dir."/".$i.".tmp")); $newFile = fopen($save,"a+"); fwrite($newFile,$writeData); fclose($newFile); fclose($readData); $resu = @unlink($dir."/".$i.".tmp"); } $res = array("res"=>"success","url"=>mb_convert_encoding($truename."-".$fsize."/".$fname,'utf-8','gbk')); echo json_encode($res); } ?>
fexjava