-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathindex.html
147 lines (121 loc) · 4.02 KB
/
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
<script type="text/javascript">
const BYTES_PER_CHUNK = 1024 * 1024; // 1MB chunk sizes.
var slices; // slices, value that gets decremented
var slicesTotal; // total amount of slices, constant once calculated
/**
* Calculates slices and indirectly uploads a chunk of a file via uploadFile()
**/
function sendRequest() {
var xhr;
var blob = document.getElementById('fileToUpload').files[0];
var start = 0;
var end;
var index = 0;
// calculate the number of slices
slices = Math.ceil(blob.size / BYTES_PER_CHUNK);
slicesTotal = 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++;
}
}
/**
* Blob to ArrayBuffer (needed ex. on Android 4.0.4)
**/
var str2ab_blobreader = function(str, callback) {
var blob;
BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;
if (typeof(BlobBuilder) !== 'undefined') {
var bb = new BlobBuilder();
bb.append(str);
blob = bb.getBlob();
} else {
blob = new Blob([str]);
}
var f = new FileReader();
f.onload = function(e) {
callback(e.target.result)
}
f.readAsArrayBuffer(blob);
}
/**
* Performs actual upload, adjustes progress bars
*
* @param blob
* @param index
* @param start
* @param end
*/
function uploadFile(blob, index, start, end) {
var xhr;
var end;
var chunk;
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.responseText) {
alert(xhr.responseText);
}
slices--;
// if we have finished all slices
if(slices == 0) {
mergeFile(blob);
}
}
};
if (blob.webkitSlice) {
chunk = blob.webkitSlice(start, end);
} else if (blob.mozSlice) {
chunk = blob.mozSlice(start, end);
} else {
chunk = blob.slice(start, end);
}
xhr.addEventListener("load", function (evt) {
var percentageDiv = document.getElementById("percent");
var progressBar = document.getElementById("progressBar");
progressBar.max = progressBar.value = 100;
percentageDiv.innerHTML = "100%";
}, false);
xhr.upload.addEventListener("progress", function (evt) {
var percentageDiv = document.getElementById("percent");
var progressBar = document.getElementById("progressBar");
if (evt.lengthComputable) {
progressBar.max = slicesTotal;
progressBar.value = index;
percentageDiv.innerHTML = Math.round(index/slicesTotal * 100) + "%";
}
}, false);
xhr.open("post", "upload.php", true);
xhr.setRequestHeader("X-File-Name", blob.name); // custom header with filename and full size
xhr.setRequestHeader("X-File-Size", blob.size);
xhr.setRequestHeader("X-Index", index); // part identifier
if (blob.webkitSlice) { // android default browser in version 4.0.4 has webkitSlice instead of slice()
var buffer = str2ab_blobreader(chunk, function(buf) { // we cannot send a blob, because body payload will be empty
xhr.send(buf); // thats why we send an ArrayBuffer
});
} else {
xhr.send(chunk); // but if we support slice() everything should be ok
}
}
/**
* Function executed once all of the slices has been sent, "TO MERGE THEM ALL!"
**/
function mergeFile(blob) {
var xhr;
var fd;
xhr = new XMLHttpRequest();
fd = new FormData();
fd.append("name", blob.name);
fd.append("index", slicesTotal);
xhr.open("POST", "merge.php", true);
xhr.send(fd);
}
</script>
<div id="percent">Waiting...</div>
<input type="file" name="file" id="fileToUpload"> <button onclick="sendRequest()">Send</button>
<progress id="progressBar" value="0" max="100"></progress>