問題描述
我正在嘗試使用 XMLHttpRequest 和 file.slice 將一些大文件上傳到服務器.
我已經在文檔和其他各種鏈接的幫助下做到了這一點.
由于上傳大文件是一項漫長的工作,我想為用戶提供一個進度條.
經過更多閱讀后,我遇到了 示例,理論上,正是我需要的.
通過獲取示例代碼并使其適應我的需求,我達到了
I am trying to upload some large files to the server using XMLHttpRequest and file.slice.
I've manage doing this with the help of documentations and other various links.
Since uploading large file is a lengthily job, i would like to provide the user with a progress bar.
After some more readings i've come across on an example that, theoretically, does exactly what i need.
By taking the sample code and adapting it to my needs i reached
var upload =
{
blobs: [],
pageName: '',
bytesPerChunk: 20 * 1024 * 1024,
currentChunk: 0,
loaded: 0,
total: 0,
file: null,
fileName: "",
uploadChunk: function (blob, fileName, fileType) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.responseText) {
// alert(xhr.responseText);
}
}
};
xhr.addEventListener("load", function (evt) {
$("#dvProgressPrcent").html("100%");
$get('dvProgress').style.width = '100%';
}, false);
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var progress = Math.ceil(((upload.loaded + evt.loaded) / upload.total) * 100);
$("#dvProgressPrcent").html(progress + "%");
$get('dvProgress').style.width = progress + '%';
}
}, false);
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var progress = Math.ceil(((upload.loaded + evt.loaded) / upload.total) * 100);
$("#dvProgressPrcent").html(progress + "%");
$get('dvProgress').style.width = progress + '%';
}
}, false);
xhr.open('POST', upload.pageName, false);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", fileName);
xhr.setRequestHeader("X-File-Type", fileType);
xhr.send(blob);
},
upload: function (file) {
var start = 0;
var end = 0;
var size = file.size;
var date = new Date();
upload.fileName = date.format("dd.MM.yyyy_HH.mm.ss") + "_" + file.name;
upload.loaded = 0;
upload.total = file.size;
while (start < size) {
end = start + upload.bytesPerChunk;
if (end > size) {
end = size;
}
var blob = file.slice(start, end);
upload.uploadChunk(blob, upload.fileName, file.type);
start = end;
upload.loaded += start;
}
return upload.fileName;
}
};
電話就像(沒有驗證)
upload.upload(document.getElementById("#upload").files[0]);
我的問題是進度事件沒有觸發.
我已經為進度事件嘗試了 xhr.addEventListener 和 xhr.upload.addEventListener (一次和一次),但它永遠不會觸發.onreadystatechange 和 load 事件觸發就好了.
My problem is that the progress event doesn't trigger.
I've tried xhr.addEventListener and with xhr.upload.addEventListener (each at a time and both at a time) for the progress event but it never triggers. The onreadystatechange and load events trigger just fine.
如果我做錯了什么,我將不勝感激
I would greatly appreciate help with what i am doing wrong
更新
經過多次嘗試,我設法模擬了一個進度,但我遇到了另一個問題:Chrome 的 UI 在上傳期間沒有更新.
現在的代碼是這樣的
Update
After many attempts i've manage to simulate a progress but i've ran into another problem: Chrome's UI is not updating during the upload.
The code looks like this now
var upload =
{
pageName: '',
bytesPerChunk: 20 * 1024 * 1024,
loaded: 0,
total: 0,
file: null,
fileName: "",
uploadFile: function () {
var size = upload.file.size;
if (upload.loaded > size) return;
var end = upload.loaded + upload.bytesPerChunk;
if (end > size) { end = size; }
var blob = upload.file.slice(upload.loaded, end);
var xhr = new XMLHttpRequest();
xhr.open('POST', upload.pageName, false);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", upload.fileName);
xhr.setRequestHeader("X-File-Type", upload.file.type);
xhr.send(blob);
upload.loaded += upload.bytesPerChunk;
setTimeout(upload.updateProgress, 100);
setTimeout(upload.uploadFile, 100);
},
upload: function (file) {
upload.file = file;
var date = new Date();
upload.fileName = date.format("dd.MM.yyyy_HH.mm.ss") + "_" + file.name;
upload.loaded = 0;
upload.total = file.size;
setTimeout(upload.uploadFile, 100);
return upload.fileName;
},
updateProgress: function () {
var progress = Math.ceil(((upload.loaded) / upload.total) * 100);
if (progress > 100) progress = 100;
$("#dvProgressPrcent").html(progress + "%");
$get('dvProgress').style.width = progress + '%';
}
};
更新 2
我已經設法修復它并模擬了一個也適用于 chrome 的進度條.
我已經用有效的代碼示例更新了之前的代碼示例.
您可以通過減小一次上傳的塊的大小來更頻繁地刷新"欄謝謝你的幫助
Update 2
I've managed to fix it and simulate a progress bar that works in chrome too.
i've updated previous code sample with the one that works.
You can make the bar 'refresh' more often by reducing the size of the chunk uploaded at a time
Tahnk you for your help
推薦答案
如 https://stackoverflow.com/a/中所述3694435/460368,你可以這樣做:
if(xhr.upload)
xhr.upload.onprogress=upload.updateProgress;
和
updateProgress: function updateProgress(evt)
{
if (evt.lengthComputable) {
var progress = Math.ceil(((upload.loaded + evt.loaded) / upload.total) * 100);
$("#dvProgressPrcent").html(progress + "%");
$get('dvProgress').style.width = progress + '%';
}
}
這篇關于使用 XMLHttpRequest 上傳大文件時的進度條的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!