en.javascript.info/archive/upload-2way.view/uploader.js
2015-03-09 18:48:58 +03:00

84 lines
No EOL
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function Uploader(file, onSuccess, onError, onProgress) {
// идентификатор загрузки, чтобы стыковать два потока
var fileId = file.name + '-' + file.size + '-' + +file.lastModifiedDate;
fileId = hashCode(fileId);
var xhrUpload;
var xhrStatus;
// *!* Закачка: поток НА сервер */!*
function runUpload(startByte) {
console.log("run upload from ", startByte);
xhrUpload = new XMLHttpRequest();
xhrUpload.onload = xhrUpload.onerror = function() {
xhrStatus.abort(); // остановить отслеживание прогресса по завершении загрузки
if (this.status != 200) {
onError("Upload error " + this.statusText);
} else {
onSuccess();
}
};
xhrUpload.open("POST", "upload", true);
xhrUpload.setRequestHeader('X-File-Id', fileId);
xhrUpload.send(file.slice(startByte));
}
// *!* Получать статус: поток С сервера */!*
function upload() {
xhrStatus = new XMLHttpRequest();
xhrStatus.onreadystatechange = function(e) {
console.log(this);
}
xhrStatus.onprogress = function() {
var lastByte = getLastProgress(xhrStatus.responseText);
console.log("lastByte", lastByte);
if (!xhrUpload) {
runUpload(lastByte + 1);
}
onProgress(lastByte, file.size);
}
xhrStatus.onerror = function() {
onError("Upload status error " + this.statusText);
xhrUpload.abort();
}
xhrStatus.open("POST", "status-stream", true);
xhrStatus.setRequestHeader('X-File-Id', fileId);
xhrStatus.send();
}
// *!* Функция для чтения количества байт из статуса сервера 12-345-... */!*
function getLastProgress(response) {
// читаем число между последним и предпоследним знаком -
var lastDelimiter = response.lastIndexOf('-');
if (lastDelimiter < 0) return 0;
var prevDelimiter = response.lastIndexOf('-', lastDelimiter - 1);
return response.slice(prevDelimiter + 1, lastDelimiter);
}
// внешний интерфейс
this.upload = upload;
}
// вспомогательная функция: получение 32-битного числа из строки
function hashCode(str) {
if (str.length == 0) return 0;
var hash = 0,
i, chr, len;
for (i = 0; i < str.length; i++) {
chr = str.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
};