我编写了以下函数来处理Ajax请求以获取数据;
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
xhr.onload = function() {
var txt1 = xhr.responsetxt1;
var heading = getheading(txt1);
if (heading == 'PASS') {
var file = "My_URL" + ".js";
downloadFile(file);
//My code to display a progress bar here?
} else {
//Logic to handle failure to load
}
};
这是我的downloadFile
函数来下载文件。但是,我不明白如何:
如果您可以添加有关其工作原理的说明,那就太棒了。感谢。
function downloadFile(fileName) {
(function(d) {
var ref = d.getElementsByTagName('script')[0];
var js = d.createElement('script');
js.src = fileName;
ref.parentNode.insertBefore(js, ref);
// My code to display a progress bar here?
}(document));
}
答案 0 :(得分:0)
AFAIK ,脚本元素没有进度事件。最好的办法是使用XHR获取脚本的正文,然后依靠浏览器缓存进行第二次获取。问题是您的脚本需要由浏览器解析,并且似乎不是事件。
我的解决方案是纯JS,因此您可以将其调整为您正在使用的任何框架。它假定实际下载大约占总时间的70%,并为浏览器解析分配20%。我使用了非常简化版本的awesome three.js 3D库作为一个较大的源文件。
因为它在另一个沙盒中,进度调用是不准确的,但是如果你提供自己不应该成为问题的脚本。
请记住,这是一个相当简单的实现。例如,我使用简单的HR作为进度条。
//this is a rough size estimate for my example file
let TOTAL_ESTIMATE = 1016 * 1024;
// I use a hr as a
let bar = document.getElementById("progressbar");
let button = document.getElementById("dlbtn");
var js; // to hold the created dom element
var fileName; // to hold my cacheBusted script adress
/* this function will be called several times during (the first) download, with info about how much data is loaded */
function onProgress(e) {
var percentComplete = e.loaded / TOTAL_ESTIMATE;
if (e.lengthComputable) {
percentComplete = e.loaded / e.total;
}
p = Math.round(percentComplete * 100);
console.log("progress", p + "%,", e.loaded, "bytes loaded")
bar.style = "width: " + (5 + .6 * p) + "%"; // I just assume dl will be around 60-70% of total time
}
/* this function is called when info comes. at the end of the initial download, the readystate will be 4 so we then set the file's src attribute, triggering a re-download but taking advantage of the browser's cache. It's not ideal, and simply `eval` ing the data would probably yield better results. I just assumed you wanted a <script> tag on your page, and for it to be evaluated. */
function onReadyState(e) {
let r = e.target;
//this is lifted almost verbatim from http://vanilla-js.com/ ;)
if (r.readyState != 4 || r.status != 200)
return;
let l = r.responseText.length;
console.log("Success !", l, "bytes total (" + Math.round(l / 1024) + " KB )");
bar.style = "width: 70%";
//just add / to next line to toggle ending methods
/* you could speed up the proces by simply eval()ing the returned js. like so (please be aware of security concerns) :
eval.bind(window)(r.responseText);
onScriptLoaded();
/*/
js.src = fileName;
bar.style = "width: 80%";
var ref = document.getElementsByTagName('script')[0];
ref.parentNode.insertBefore(js, ref);
//*/
};
//this is called when the script has been evaluated :
function onScriptLoaded() {
bar.style = "width: 100%; background-color: lightgreen;";
button.disabled = false;
console.log("script has been evaluated ?", THREE ? "yes" : "no"); // the demo file exposes window.THREE
}
function downloadFile(file) {
button.disabled = true;
(function(d) {
// this helps to test this script multiple times. don't keep it
fileName = file + "?bustCache=" + new Date().getTime();
console.log("inserting new script");
js = d.createElement('script');
js.type = "text/javascript";
js.defer = "defer";
js.async = "async";
var r = new XMLHttpRequest();
bar.style = "width: 5%"; //always react ASAP
r.addEventListener("progress", onProgress);
r.open("GET", fileName, true);
r.onreadystatechange = onReadyState;
js.onload = onScriptLoaded;
r.send();
// My code to display a progress bar here?
}(document));
}
&#13;
#progressbar {
height: 6px;
border-radius: 3px;
width: 0%;
border-color: green;
background-color: green;
}
&#13;
<button onclick="downloadFile('https://rawgit.com/mrdoob/three.js/dev/build/three.js', this)" id="dlbtn">Download</button>
<script id="dummy" type="text/javascript">
console.log("dummy script ready")
</script>
<hr id="progressbar" align="left" />
&#13;
答案 1 :(得分:0)
嗯,这更多地取决于编程语言而不是客户端。例如,PHP有http://php.net/manual/en/session.upload-progress.php
至于客户方,鲍里斯的答案就是一个很好的例子!希望它有所帮助。
答案 2 :(得分:0)
免责声明:我没有在Android
上对此进行测试。我只在Chrome
(桌面)中测试过。您应该看到写入浏览器控制台的进度事件
var url = 'url/to/file/';
var request = new XMLHttpRequest();
request.responseType = "blob"; // Not sure if this is needed
request.open("POST", url);
var self = this;
request.onreadystatechange = function () {
if (request.readyState === 4) {
var file = $(self).data('file');
var anchor = document.createElement('a');
anchor.download = file;
anchor.href = window.URL.createObjectURL(request.response);
anchor.click();
}
};
request.addEventListener("progress", function (e) {
if(e.lengthComputable) {
var completedPercentage = e.loaded / e.total;
console.log("Completed: ", completedPercentage , "%");
}
}, false);
request.send();
希望这有帮助。