tml5文件分割上傳解決方案
html5提供的文件API中可以輕松的對文件進行分割切片, 然后通過javascript異步處理向服務器傳輸數據, 突破對大文件上傳的限制, 同時異步處理在一定程度上也提高了文件上傳的效率。用戶體驗上也優于前述方案。
index.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>大文件上傳實例</title>
<script type="text/javascript">
const BYTES_PER_CHUNK = 1024 * 1024; // 每個文件切片大小定為1MB .
var slices;
var totalSlices;
//發送請求
function sendRequest() {
var blob = document.getElementById('file').files[0];
var start = 0;
var end;
var index = 0;
// 計算文件切片總數
slices = Math.ceil(blob.size / BYTES_PER_CHUNK);
totalSlices= slices;
while(start < blob.size) {
end = start + BYTES_PER_CHUNK;
if(end > blob.size) {
end = blob.size;
}
uploadFile(blob, index, start, end);
start = end;
index++;
}
}
//上傳文件
function uploadFile(blob, index, start, end) {
var xhr;
var fd;
var chunk;
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.responseText) {
alert(xhr.responseText);
}
slices--;
// 如果所有文件切片都成功發送,發送文件合并請求。
if(slices == 0) {
mergeFile(blob);
alert('文件上傳完畢');
}
}
};
chunk =blob.slice(start,end);//切割文件
//構造form數據
fd = new FormData();
fd.append("file", chunk);
fd.append("name", blob.name);
fd.append("index", index);
xhr.open("POST", "upload.php", true);
//設置二進制文邊界件頭
xhr.setRequestHeader("X_Requested_With", location.href.split("/")[3].replace(/[^a-z]+/g, '$'));
xhr.send(fd);
}
function mergeFile(blob) {
var xhr;
var fd;
xhr = new XMLHttpRequest();
fd = new FormData();
fd.append("name", blob.name);
fd.append("index", totalSlices);
xhr.open("POST", "merge.php", true);
xhr.setRequestHeader("X_Requested_With", location.href.split("/")[3].replace(/[^a-z]+/g, '$'));
xhr.send(fd);
}
</script>
</head>
<body>
<input type="file" id="file"/>
<button onclick="sendRequest()">上傳</button>
</body>
</html>
upload.php
<?php
//省略了文件接收判斷isset部分
//當前目錄下建立一個uploads文件夾
//接收文件名時進行轉碼,防止中文亂碼。
$target = "uploads/" .iconv("utf-8","gbk",$_POST["name"]) . '-' . $_POST['index'];
move_uploaded_file($_FILES['file']['tmp_name'], $target);
// Might execute too quickly.
sleep(1);
?>
merge.php
<?php
//文件合并
$target = "uploads/" .iconv("utf-8","gbk",$_POST["name"]);
$dst = fopen($target, 'wb');
for($i = 0; $i < $_POST['index']; $i++) {
$slice = $target . '-' . $i;
$src = fopen($slice, 'rb');
stream_copy_to_stream($src, $dst);
fclose($src);
unlink($slice);
}
fclose($dst);
關鍵函數stream_copy_to_stream()
int stream_copy_to_stream ( resource $source , resource $dest [, int $maxlength = -1 [, int $offset = 0 ]] )
<?php
$src = fopen('http://www.example.com', 'r');
$dest1 = fopen('first1k.txt', 'w');
$dest2 = fopen('remainder.txt', 'w');
echo stream_copy_to_stream($src, $dest1, 1024) . " bytes copied to first1k.txt\n";
echo stream_copy_to_stream($src, $dest2) . " bytes copied to remainder.txt\n";
?>
var blob = document.getElementById('file').files[0];
console.dir(blob);
相關的屬性如下:
lastModified: 1511081596000
lastModifiedDate: Sun Nov 19 2017 16:53:16 GMT+0800 (中國標準時間) {}
name: "IMG_20171119_165316.jpg"
size: 4383101
type: "image/jpeg"
slice: ? slice() 用于切割文件
后臺看到訪問記錄,很多用戶提了這個需求,要求用HTML5來實現。網上搜了一下,發現這類需求很多,相關的文章和代碼也很多,大部分用的是VUE,H5的也有,不過只提供了前端部分,后端的沒有。然后也不完善,花了很多的時間找了一些,有的用是能用,但是小問題太多,找這些能用的代碼,所花的時間都能夠完全自已寫一個出來了。很多代碼后續維護也是個問題,找不到原技術人員,也沒有完善的文檔,開發維護都靠自已,這樣花的時間有點不值得。
代碼:https://gitee.com/xproer/up6-vue-cli
1.引入up6組件
2.配置接口地址
接口地址分別對應:文件初始化,文件數據上傳,文件進度,文件上傳完畢,文件刪除,文件夾初始化,文件夾刪除,文件列表
參考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de
3.定義事件
TML5實現大文件上傳下載,HTML5實現大文件上傳下載解決方案,HTML5實現大文件上傳下載思路,HTML5實現大文件上傳下載源碼,HTML5實現大文件上傳下載實例,HTML5實現大文件分塊上傳下載,HTML5實現大文件分片上傳下載,HTML5實現大文件切片上傳下載,HTML5實現大文件加密上傳下載,HTML5實現文件夾上傳下載,
用戶上傳的文件比較大,有20G左右,直接用HTML傳的話容易失敗,服務器也容易出錯,需要分片,分塊,分割上傳。也就是將一個大的文件分成若干個小文件塊來上傳,另外就是需要實現秒傳功能和防重復功能,秒傳就是用戶如果上傳過這個文件,那么直接在數據庫中查找記錄就行了,不用再上傳一次,節省時間,實現的思路是對文件做MD5計算,將MD5值保存到數據庫,算法可以用MD5,或者CRC,或者SHA1,這個隨便哪個算法都行。
分片還需要支持斷點續傳,現在HTML5雖然提供了信息記錄功能,但是只支持到了會話級,也就是用戶不能關閉瀏覽器,也不能清空緩存。但是有的政府單位上傳大文件,傳了一半下班了,明天繼續傳,電腦一關結果進度信息就丟失了,這個是他們的一個痛點。
切片的話還有一點就是在服務器上合并,一個文件的所有分片數據上傳完后需要在服務器端進行合并操作。
支持文件下載,批量下載,下載斷點續傳,加密下載,端到端加密,加密算法支持國密SM4,多線程下載
支持在服務端保存文件夾層級結構,支持將文件夾層級結構信息保存到數據庫中,支持下載時能夠將文件夾層級結構下載下來,支持下載文件夾,下載文件夾支持斷點續傳,
支持加密傳輸,包括加密上傳,加密下載,加密算法支持國密SM4,
對于大文件的處理,無論是用戶端還是服務端,如果一次性進行讀取發送、接收都是不可取,很容易導致內存問題。所以對于大文件上傳,采用切塊分段上傳
從上傳的效率來看,利用多線程并發上傳能夠達到最大效率。
1.下載示例
https://gitee.com/xproer/up6-vue-cli
將up6組件復制到項目中
示例中已經包含此目錄
1.引入up6組件
2.配置接口地址
接口地址分別對應:文件初始化,文件數據上傳,文件進度,文件上傳完畢,文件刪除,文件夾初始化,文件夾刪除,文件列表
參考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de
3.處理事件
啟動測試
啟動成功
效果
數據庫
源碼工程文檔:https://drive.weixin.qq.com/s?k=ACoAYgezAAw1dWofra
源碼報價單:https://drive.weixin.qq.com/s?k=ACoAYgezAAwoiul8gl
OEM版報價單:https://drive.weixin.qq.com/s?k=ACoAYgezAAwuzp4W0a
產品源代碼:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc
授權碼生成器:https://drive.weixin.qq.com/s?k=ACoAYgezAAwTIcFph1
*請認真填寫需求信息,我們會在24小時內與您取得聯系。