關(guān)于大文件上傳 思路
使用js讀取form表單中選擇的file,計(jì)算文件md5值,并上傳md5值到服務(wù)端,檢查文件是否已上傳過(類似秒傳功能)
若文件未上傳過,按照其大小切成1MB大小的塊,小于1MB的不用切
用ajax異步提交切好的塊上傳至服務(wù)端(一個(gè)塊一個(gè)請求,不阻塞,多線程)
當(dāng)上傳完成所有切塊,發(fā)起一個(gè)合并文件的請求,服務(wù)端進(jìn)行前面上傳的文件塊的合并,合并完成即上傳完成。
實(shí)現(xiàn)js計(jì)算文件md5使用spark-md5.js,據(jù)說這個(gè)庫使用的是世界上最快的md5算法。
js對文件切片并使用ajax上傳切片:
let size = file.size; //獲取文件大小 const shardSize = 1024 * 1024; // 塊大小1MB let shardCount = Math.ceil(size/shardSize); //可切成的塊數(shù) for(let i = 0; i < shardCount; i++){ let start = i * shardSize, end = Math.min(size, start + shardSize); let form = new FormData(); form.append("file", file.slice(start, end)); //用slice方法切片 form.append("size", end - start); form.append("name", name); form.append("total", shardCount); form.append("md5", file_md5); //文件md5值 form.append("index", i); //第幾塊 $.ajax({ url: "upload.php?type=shard", type: "POST", data: form, // async: false, //是否異步上傳,默認(rèn)true processData: false, //很重要,告訴jquery不要對form進(jìn)行處理 contentType: false, //很重要,指定為false才能形成正確的Content-Type success: function (res) { // 成功回調(diào) } } }
php端保存切片
$path = __DIR__ . "/uploads"; $file = $_FILES["file"]; $total = $_POST["total"]; $index = $_POST["index"]; $size = $_POST["size"]; $dst_file = $path . "/" . $name . "-" . $total . ":" . $index; // 切片文件存儲的文件名 if ($file["error"] > 0) { echo json_encode(["code"=>400, "msg"=>$file["error"]]);die; } else { $res = move_uploaded_file($file["tmp_name"], $dst_file); if ($res) { file_put_contents($dst_file . ".info", $size); // 切片上傳成功,寫一個(gè)保存其大小的文件,后續(xù)合并是校驗(yàn)文件用的到 echo json_encode(["code"=>200, "msg"=>"shard ok"]);die; } else { echo json_encode(["code"=>400, "msg"=>"shard move_uploaded_file error"]);die; } }
php端合并
function mergeFile($name, $total, &$msg) { // 校驗(yàn)切片文件是否都上傳完成,是否完整 for ($i = 0; $i < $total; $i++) { if (!file_exists($name . "-" . $total . ":" . $i . ".info") || !file_exists($name . "-" . $total . ":" . $i)) { $msg = "shard error $i"; return false; } else if (filesize($name . "-" . $total . ":" . $i) != file_get_contents($name . "-" . $total . ":" . $i . ".info")) { $msg = "shard size error $i"; return false; } } @unlink($name); if (file_exists($name . ".lock")) { //加鎖 防止有其他進(jìn)程寫文件,造成文件損壞 $msg = "on lock"; return false; } touch($name . ".lock"); $file = fopen($name, "a+"); for ($i = 0; $i < $total; $i++) { //按切片順序?qū)懭胛募? $shardFile = fopen($name . "-" . $total . ":" . $i, "r"); $shardData = fread($shardFile, filesize($name . "-" . $total . ":" . $i)); fwrite($file, $shardData); fclose($shardFile); unlink($name . "-" . $total . ":" . $i); unlink($name . "-" . $total . ":" . $i . ".info"); } fclose($file); unlink($name . ".lock"); return true; }
我也寫好了一個(gè)demo,傳送門
下面是這個(gè)demo的效果圖:
這個(gè)demo有些方面還不夠完善,后續(xù)持續(xù)完善吧~
原文連接:
關(guān)于大文件上傳
更多分享知識點(diǎn),請掃碼關(guān)注微信公眾號:
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/31568.html
showImg(https://segmentfault.com/img/bVbs1lu?w=675&h=221); 關(guān)于大文件上傳 思路 使用js讀取form表單中選擇的file,計(jì)算文件md5值,并上傳md5值到服務(wù)端,檢查文件是否已上傳過(類似秒傳功能) 若文件未上傳過,按照其大小切成1MB大小的塊,小于1MB的不用切 用ajax異步提交切好的塊上傳至服務(wù)端(一個(gè)塊一個(gè)請求,不阻塞,多線程...
摘要:,在后續(xù)測試時(shí)遇到一個(gè)詭異,當(dāng)文件過大時(shí),任務(wù)腳本上傳到七牛云失敗。當(dāng)我遇到大文件無法上傳到七牛云時(shí),斷點(diǎn)調(diào)試到這里,發(fā)現(xiàn)返回的是。后來還真被我找到了,七牛云官方提供一個(gè)腳本工具。 業(yè)務(wù)場景 需求 我們項(xiàng)目有一個(gè)文件上傳需求,需要從客戶端上傳到七牛云的對象存儲和自己的應(yīng)用服務(wù)器上。這里使用七牛云主要是實(shí)現(xiàn)下載分發(fā)。應(yīng)用服務(wù)器需要留一份是因?yàn)楹罄m(xù)需要做文件分析(并且是上傳后需要立馬分析出...
摘要:數(shù)據(jù)遷移過程中的速率問題。關(guān)閉源站數(shù)據(jù)遷移典型案例剖析七牛客戶陌陌的數(shù)據(jù)量非常大,如果采用常用的傳輸辦法,整個(gè)遷移過程要耗時(shí)半年,并且會嚴(yán)重影響線上的業(yè)務(wù)。為此,七牛為陌陌制定了個(gè)性化的數(shù)據(jù)遷移方案。 showImg(http://sharlyne-lee.qiniudn.com/m1.png); 無論是計(jì)劃擁抱云服務(wù)還是打算從正在使用的云服務(wù)切換到另外一家,這其中數(shù)據(jù)的遷移是很關(guān)鍵...
摘要:沒有瀏覽器測試,所以不知道是不是有效,其實(shí)里面看起來比我寫的那個(gè)復(fù)雜,實(shí)際上多了個(gè)檢驗(yàn)格式上兼容寫法所以不要怕,如果我錯(cuò)了記得提醒下我啊。目前為止其實(shí)已經(jīng)該說的都差不多覆蓋到了吧,動(dòng)手能力強(qiáng)的話已經(jīng)可以根據(jù)教程寫一個(gè)實(shí)例出來的了。 系列文章 關(guān)于前端上傳文件全面基礎(chǔ)掃盲貼(零)關(guān)于前端上傳文件全面基礎(chǔ)掃盲貼(一) ----- XMLHttpRequest關(guān)于前端上傳文件全面基礎(chǔ)掃盲貼(...
摘要:文章出處最近項(xiàng)目中有一個(gè)文件上傳的功能,可以上傳壓縮包文件,遇到一個(gè)問題,就是個(gè)別電腦點(diǎn)擊上傳控件時(shí),需要四五秒左右才會有反應(yīng)。由于我們請求不到海外服務(wù)器,會等到連接誒失敗,才會彈出上傳文件窗口。 文章出處:http://www.jianshu.com/p/be34... 最近項(xiàng)目中有一個(gè)文件上傳的功能,可以上傳壓縮包文件,遇到一個(gè)問題,就是個(gè)別電腦點(diǎn)擊上傳控件時(shí),需要四五秒左右才會有...
閱讀 1476·2023-04-26 00:08
閱讀 811·2021-11-23 18:51
閱讀 1683·2021-11-12 10:34
閱讀 1018·2021-10-14 09:43
閱讀 509·2021-08-18 10:23
閱讀 2589·2019-08-30 15:55
閱讀 3399·2019-08-30 11:05
閱讀 2799·2019-08-29 12:50