Я пытаюсь смастерить функцию скачивания с прогрессом. Мне нужно получать прогресс в процентах. Я загрузил 3 файла на github: 5mb.txt 10mb.txt и 20mb.txt. Их я пытаюсь прочитать.
Так как при прямом обращении к файлу через api я не могу получить его содержимое (так работает api github), то получение содержимого происходит в 2 этапа. Первый запрос на файл,а затем на blob. При первом запросе я получаю его размер, который соответствует 5000000 (5мб) и ссылку на blob. Следом, когда я делаю запрос на blob и смотрю прогресс загрузки, то я получаю каждый раз в результате ~137%.
Когда я получаю blob, то я не получаю конкретно файл, а так же, как и в первом случае, получаю json объект, где в ключе content находится мой файл. Разумеется размер blob запроса не будет на 100% соответствовать значению size из первого запроса, так как во втором запросе мне также возвращаются другие ключи (encoding, sha, size, node_id, url).
Но эти ключи каждый раз имеют плюс минус одинаковый размер, поэтому они сразу отметаются.
В случае скачивания файла на
5мб - я получаю 6889205 байт
10мб - 13778096 байт
20мб - 27555872 байт
Каждый раз полученный размер на ~37% больше, чем заданный. Вот откуда он в последнем файле взял 7мб?
Код можете запустить из консоли
Код
function makeRequest(method, url, data = false) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.upload.onprogress = function(event) {
if (event.lengthComputable) {
var percentComplete = (event.loaded / event.total) * 100;
console.log('Прогресс загрузки:', percentComplete.toFixed(2) + '%');
}
};
if (method = 'GET' && data) {
xhr.onprogress = (event) => {
let percentComplete = (event.loaded / data) * 100;
console.log(`Получено с сервера ${percentComplete}%. загружено ${event.loaded}`);
}
}
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.response));
} else {
reject(xhr.statusText);
}
};
xhr.onerror = function() {
reject(xhr.statusText);
};
if (data && method === 'PUT') {
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
xhr.send(JSON.stringify(data));
} else {
xhr.send();
}
});
}
makeRequest('GET', "https://api.github.com/repos/accountnujen/testa/contents/10mb.txt")
.then(data => {
console.log(data);
let size = data.size;
makeRequest('GET',data.git_url,size)
.then(data => {
console.log(data);
})
}).catch(error => {
console.log(error);
})