重點講解了多文件上傳,大文件上傳,分塊上傳,斷點續傳,文件秒傳,上傳失敗自動修復再上傳等功能,只要你按照課程中講解的做,上傳3、5個G,那都不是事。特別是大文件秒傳功能,不僅節省了上傳時間,還節省了網絡帶寬和服務器空間。
我們平時做業務系統的時候,一般都會使用表單提交數據,提交數據的時候常常又伴隨着附件的上傳,如果附件小,用傳統的辦法就能解決,如果附件比較大,比如板給你安排一個上傳視頻的任務,視頻文件一般都比較大,動不動就是幾個G,用傳統的辦法就顯得非常有限。爲了幫助大家解決大文件上傳的問題,我們特別錄製了本套視頻教程,本套視頻教程高度壓縮的精華版,沒有廢話,重點講解了多文件上傳,大文件上傳,分塊上傳,斷點續傳,文件秒傳,上傳失敗自動修復再上傳等功能,只要你按照課程中講解的做,上傳3、5個G,那都不是事。特別是大文件秒傳功能,不僅節省了上傳時間,還節省了網絡帶寬和服務器空間,採用md5加密標識文件唯一性,避免了同一文件的重複上傳,上傳過程帶進度條,即時顯示上載數據量和上載百分比。求人不如求己,搞定這些技術,讓老闆加薪,再也不用低三下四的求人,大文件上傳無壓力,讓學習更高效,讓工作更輕鬆,媽媽再也不用擔心你的學習!
直接上代碼:
前臺前端index.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
|
<!
DOCTYPE
html>
<
html
>
<
head
>
<
meta
charset="utf-8" />
<
title
>夜鷹教程網大文件分塊上傳</
title
>
<
style
type="text/css">
* {
font-family: "微軟雅黑";
margin: 0;
padding: 0;
}
.container {
padding-top: 10px;
padding-left: 10px;
}
.container input {
width: 120px;
height: 30px;
background-color: blue;
color: white;
border: 0;
line-height: 30px;
border-radius: 5px;
margin-right: 5px;
outline: none;
cursor: pointer;
}
#filelist {
width: 800px;
border: solid 1px #eee;
border-collapse: collapse;
margin: 10px;
}
#filelist td {
border-bottom: solid 1px #eee;
height: 30px;
font-size: 12px;
/*line-height:30px ;*/
padding: 0 3px;
}
.filename {
width: 200px;
text-align: center;
}
.filestatus {
width: 100px;
text-align: center;
}
.fileprogress {
text-align: center;
}
.domprogress {
width: 320px;
}
.domsize {
display: block;
}
#tdmsg {
text-align: center;
}
#fileselect {
display: none;
}
span.domtime {
display:block;
}
</
style
>
</
head
>
<
body
>
<
div
class="container">
<
input
type="file" name="fileselect" id="fileselect" value="" multiple/>
<
input
type="button" id="btnselect" value="選擇上傳的文件" />
<
input
type="button" id="btnupload" value="開始上傳" />
</
div
>
<
table
cellspacing="0" cellpadding="0" id="filelist">
<
tr
>
<
td
class="filename">文件名</
td
>
<
td
class="fileprogress">進度</
td
>
<
td
class="filestatus">狀態</
td
>
</
tr
>
<!--<tr><td>人民的名義.avi </td><td><progress value="10" max="100" class="domprogress"></progress><span class="dompercent">10%</span><span class="domsize">0/1.86GB</span></td><td class="filestatus"><span class="domstatus">排隊中</span></td></tr>-->
<
tr
id="trmsg">
<
td
colspan="3" id="tdmsg">請選擇要上傳的文件! 技術支持QQ:1416759661</
td
>
</
tr
>
</
table
>
<
script
src="js/jquery-1.11.0.js" type="text/javascript" charset="utf-8"></
script
>
<
script
src="js/spark-md5.js" type="text/javascript" charset="utf-8"></
script
>
<
script
type="text/javascript">
$("#btnselect").click(function() {
$("#fileselect").click();
});
$("#fileselect").change(function() {
var files = this.files;
if(files.length > 0) {
$("#trmsg").remove();
$(files).each(function(index, item) {
console.log(index, item);
var filesize = 0;
if((item.size / 1024 / 1024 / 1024) >= 1) {
filesize = (item.size / 1024 / 1024 / 1024).toFixed(2) + "GB"; // b=>kb=>mb=>gb
} else if((item.size / 1024 / 1024 / 1024) <
1
&& (item.size / 1024 / 1024) >= 1) {
filesize = (item.size / 1024 / 1024).toFixed(2) + "MB";
} else if((item.size / 1024 / 1024) <
1
&& (item.size / 1024) >= 1) {
filesize = (item.size / 1024).toFixed(2) + "KB";
} else {
filesize = item.size + "B";
}
var htmlstr = '<
tr
><
td
>' + item.name + '</
td
><
td
><
progress
value="0" max="100" class="domprogress"></
progress
><
span
class="dompercent"> 0/'+filesize+'</
span
><
span
class="domtime">總共耗時:0 秒</
span
></
td
><
td
class="filestatus"><
span
class="domstatus">排隊中</
span
></
td
></
tr
>';
$("#filelist").append(htmlstr);
});
}
});
$("#btnupload").click(function() {
var files = $("#fileselect")[0].files;
$(files).each(function (index, item) {
yyupload(files[index], $("span.domstatus").eq(index), $("span.dompercent").eq(index), $(".domprogress").eq(index), $("span.domtime").eq(index));
});
});
//文件上傳
function yyupload(file, dommsg, dompercentmb, domprogress, domtime, fn) {
var startTime = new Date();
//獲取文件的md5字符串,用於標識文件的唯一性。
calculate(file);
//獲取文件的加密字符串
function calculate(file) {
var fileReader = new FileReader();
var chunkSize = 1024 * 1024 * 5; //每次讀取5MB
var chunksCount = Math.ceil(file.size / chunkSize); //回大於參數x的最小整數 8=》8 8.4=》9 8.5=》9 -8.5=》-8
var currentChunk = 0; //當前塊的索引
var spark = new SparkMD5();
fileReader.onload = function(e) {
console.log((currentChunk + 1) + "/" + chunksCount)
dommsg.text("正在檢查文件: " + (currentChunk + 1) + "/" + chunksCount);
spark.appendBinary(e.target.result); // 添加二進制字符串
currentChunk++;
if(currentChunk <
chunksCount
) {
loadNext();
} else {
var md5value = spark.end();
console.log("文件加密結束,密鑰爲:" + md5value);
checkfile(md5value, file); //檢查服務器是否存在該文件,存在就從斷點繼續上傳
}
};
function loadNext() {
var start = currentChunk * chunkSize; //計算讀取開始位置
var end = start + chunkSize >= file.size ? file.size : start + chunkSize; //計算讀取結束位置
fileReader.readAsBinaryString(file.slice(start, end)); //讀取爲二進制字符串
};
loadNext();
}
var repeatcount = 0;
//檢查文件是否已經存在
function checkfile(md5value, file) {
var fd = new FormData();
fd.append('rquesttype', "chekcfile");
fd.append('filename', file.name);
fd.append('md5value', md5value);
var xhr = new XMLHttpRequest();
xhr.open('post', 'FileUpoload.ashx', true);
xhr.onreadystatechange = function(res) {
if(xhr.readyState == 4 && xhr.status == 200) {
var jsonobj = JSON.parse(xhr.responseText); //可以將json字符串轉換成json對象 //JSON.stringify(jsonobj); //可以將json對象轉換成json對符串
console.log("繼續上傳的位置:" + jsonobj.startindex);
switch(jsonobj.flag) {
case "0":
doUpload(md5value, file, 0);
break;
case "1":
doUpload(md5value, file, parseInt(jsonobj.startindex));
break;
case "2":
secondUpload(file);
break;
}
repeatcount = 0;
} else if(xhr.status == 500) {
setTimeout(function() {
if(repeatcount <
3
) {
checkfile(md5value, file);
}
repeatcount++;
}, 3000);
}
}
//開始發送
xhr.send(fd);
}
//實現秒傳功能
function secondUpload(file)
{
var timerange = (new Date().getTime() - startTime.getTime()) / 1000;
domtime.text("耗時" + timerange + "秒");
//顯示結果進度
var percent =100;
dommsg.text(percent.toFixed(2) + "%");
domprogress.val(percent);
var total = file.size;
if (total > 1024 * 1024 * 1024) {
dompercentmb.text((total / 1024 / 1024 / 1024).toFixed(2) + "GB/" + (total / 1024 / 1024 / 1024).toFixed(2) + "GB");
} else if (total > 1024 * 1024) {
dompercentmb.text((total / 1024 / 1024).toFixed(2) + "MB/" + (total / 1024 / 1024).toFixed(2) + "MB");
} else if (total > 1024 && total <
1024
* 1024) {
dompercentmb.text((total / 1024).toFixed(2) + "KB/" + (total / 1024).toFixed(2) + "KB");
} else {
dompercentmb.text((total).toFixed(2) + "B/" + (total).toFixed(2) + "B");
}
}
//上傳文件
function doUpload(md5value,file,startindex) {
var reader = new FileReader();//新建一個讀文件的對象
var step = 1024 * 200; //每次讀取文件大小 200KB
var cuLoaded = startindex; //當前已經讀取總數
var total = file.size;//文件的總大小
//讀取一段成功
reader.onload = function (e) {
//處理讀取的結果
var result = reader.result; //本次讀取的數據
var loaded = e.loaded; //本次讀取的數據長度
uploadFile(result, cuLoaded, function () { //將分段數據上傳到服務器
cuLoaded += loaded; //如果沒有讀完,繼續
var timerange = (new Date().getTime() - startTime.getTime()) / 1000;
if (total > 1024 * 1024 * 1024) {
dompercentmb.text((cuLoaded / 1024 / 1024 / 1024).toFixed(2) + "GB/" + (total / 1024 / 1024 / 1024).toFixed(2) + "GB");
} else if (total > 1024 * 1024) {
dompercentmb.text((cuLoaded / 1024 / 1024).toFixed(2) + "MB/" + (total / 1024 / 1024).toFixed(2) + "MB");
} else if (total > 1024 && total <
1024
* 1024) {
dompercentmb.text((cuLoaded / 1024).toFixed(2) + "KB/" + (total / 1024).toFixed(2) + "KB");
} else {
dompercentmb.text((cuLoaded).toFixed(2) + "B/" + (total).toFixed(2) + "B");
}
domtime.text("耗時" + timerange + "秒");
if (cuLoaded < total) {
readBlob(cuLoaded);
} else {
console.log('總共用時:' + timerange);
cuLoaded = total;
sendfinish(); //告知服務器上傳完畢
domtime.text("上傳完成,總共耗時" + timerange + "秒");
}
//顯示結果進度
var percent = (cuLoaded/total) * 100;
dommsg.text(percent.toFixed(2) + "%");
domprogress.val(percent);
});
}
var k = 0;
function sendfinish() {
var fd = new FormData();
fd.append('rquesttype', "finishupload");
fd.append('filename', file.name);
fd.append('md5value', md5value);
fd.append('totalsize', file.size);
var xhr = new XMLHttpRequest();
xhr.open('post', 'FileUpoload.ashx', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
if (fn) {
fn(); //如果上傳成功,繼續上傳下一個文件
}
k = 0;
} else if (xhr.status == 500) {
setTimeout(function () {
if (k < 3) {
sendfinish();
//上傳完畢的前端處理
}
k++
}, 3000);
}
}
//開始發送
xhr.send(fd);
}
var m = 0;
//關鍵代碼上傳到服務器
function uploadFile(result, startIndex, onSuccess) {
var blob = new Blob([result]);
//提交到服務器
var fd = new FormData();
fd.append('file', blob);
fd.append('rquesttype',"uploadblob");
fd.append('filename', file.name);
fd.append('md5value', md5value);
fd.append('loaded', startIndex);
var xhr = new XMLHttpRequest();
xhr.open('post', 'FileUpoload.ashx', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
m = 0;
if (onSuccess)
onSuccess();
} else if (xhr.status == 500) {
setTimeout(function () {
if (m < 3) {
containue();
m++;
}
}, 1000);
}
}
//開始發送
xhr.send(fd);
}
//指定開始位置,分塊讀取文件
function readBlob(start) {
//指定開始位置和結束位置讀取文件
var blob = file.slice(start, start + step); //讀取開始位置和結束位置的文件
reader.readAsArrayBuffer(blob); //讀取切割好的文件塊
}
//繼續
function containue() {
readBlob(cuLoaded);
}
readBlob(cuLoaded);
}
}
</script>
</
body
>
</
html
>
|
需要到網上下載一個spark-md5.js文件,下載地址:
https://raw.githubusercontent.com/satazor/SparkMD5/master/spark-md5.js
後端處理請求的文件FileUpoload.ashx代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|