利用slice(start,end)方法對文件進行區域式的一個切割,每一個小部分一小部分的傳過去 后台接收 並且存儲
繼續和停止的判斷就是最簡單的頁面變量來實現的定義全局的
這里我已經寫的很簡單了 但是還是有不足的地方 有需求大家下面留言提問 有bug 望大家改善也分享給我····差不多了該關電腦了·····
html頁面:
<style type="text/css">
#result{
width:500px;
height:30px;
border:1px solid green;
}
#progress {
width: 0%;
height:100%;
background:green;
}
</style>
<body>
<div id="result">
<div id="progress"></div>
</div>
<input type="file" id="file"/>
<button id="bg_to">上傳</button>
<button onclick="sendStop()">停止</button>
<button onclick="sendStart()">繼續</button>
</body>
js里面主要是3部分的
<script type="text/javascript">
const BYTES_PER_CHUNK = 1024*1024; // 每個文件切片大小定為0.5MB .
var slices;
var totalSlices;
var start = 0;
var end=BYTES_PER_CHUNK;
var index = 0;
var stop = 0
$("#bg_to").click(function(){
var file=$("#file");
if($.trim(file.val())==''){
alert("請選擇文件");
return false;
}
sendRequest()
})
function sendStop(){
if(start==0){
alert("未檢測到文件上傳")
return false
}
stop = 1
}
function sendStart(){
if(start==0){
alert("未檢測到文件上傳")
return false
}
stop = 0
sendRequest();
}
//發送請求
sendRequest = function () {
var blob = document.getElementById('file').files[0];
// 計算文件切片總數
slices = Math.ceil(blob.size / BYTES_PER_CHUNK);
totalSlices= slices;
if(stop==1){
alert("停止上傳");
return false
}
if(start < blob.size) {
if(end > blob.size) {
end = blob.size;
}
uploadFile(blob, index, start, end);
start = end;
end = start + BYTES_PER_CHUNK;
index++;
}
}
//上傳文件
uploadFile = function (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);
}
if(slices>1){
slices--;
}
var percent=100*index/slices;
if(percent>100){
percent=100;
}else if(percent==0&&slices==1){
percent=100;
}
document.getElementById('progress').style.width=percent+'%';
document.getElementById('progress').innerHTML=parseInt(percent)+'%';
// 如果所有文件切片都成功發送,發送文件合並請求。
if(percent == 100) {
mergeFile(blob);
start=0;
alert('文件上傳完畢');
}else{
if(stop!=1){ sendRequest();
} } } };
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); }
mergeFile = function (blob) { var xhr; var fd; xhr = new XMLHttpRequest(); fd = new FormData();
fd.append("name", blob.name); fd.append("index", totalSlices); xhr.open("POST", "mer_add.php", true);
xhr.setRequestHeader("X_Requested_With", location.href.split("/")[3].replace(/[^a-z]+/g, '$'));
xhr.send(fd); }</script>
upload.php 負責接收數據 將切片存儲起來
<?php
$target = "files/" .iconv("utf-8","gbk",$_POST["name"]) . '-' . $_POST['index']; //接收文件名時進行轉碼,防止中文亂碼。
move_uploaded_file($_FILES['file']['tmp_name'], $target);
sleep(1);
mer_add.php 負責將所有的切片組裝成圖片
<?php
//文件合並
$target = "files/" .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);