mod_uploadprogress is back 10
In my ongoing efforts in restructuring the core of lighttpd for the 1.5.0 release I brought mod_uploadprogress back to life.
I talked about mod_uploadprogress a long time ago and since then I got at least one request per month to bring it back again.
It was changed abit since the early days. Instead of XML we send out JSON now. That does the same and easier to parse:
{ 'state' : 'starting' };
...
{ 'state' : 'uploading', 'size' : 87901150, 'received' : 80601372};
{ 'state' : 'done', 'size' : 87901150, 'received' : 87901150};
First you need a file-upload form. It is all standard and only calls our upload-progress updater onSubmit.
<form id="upload" enctype="multipart/form-data"
action="/upload.php" method="post"
onsubmit="openProgressBar(); return true;">
<input type="hidden" name="MAX_FILE_SIZE" value="30000000" />
<input name="userfile" type="file" label="fileupload" />
<input type="submit" value="Send File" />
</form>
The progress bar in this case are 2 nested div-tags:
<div>
<div id="progress" style="width: 400px; border: 1px solid black">
<div id="progressbar"
style="width: 1px; background-color: black; border: 1px solid white">
</div>
</div>
<div id="tp">(throughput)</div>
</div>
Some Javascript with XMLHTTPRequest can tell us about the state of a upload:
<script type="text/javascript">
interval = null;
function fetch(uuid) {
req = new XMLHttpRequest();
req.open("GET", "/progress", 1);
req.setRequestHeader("X-Progress-Id", uuid);
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (req.status == 200) {
/* poor-man JSON parser */
var upload = eval(req.responseText);
document.getElementById('tp').innerHTML = upload.state;
/* change the width if the inner progress-bar */
if (upload.state == 'done' || upload.state == 'uploading') {
bar = document.getElementById('progressbar');
w = 400 * upload.received / upload.size;
bar.style.width = w + 'px';
}
/* we are done, stop the interval */
if (upload.state == 'done') {
window.clearTimeout(interval);
}
}
}
}
req.send(null);
}
function openProgressBar() {
/* generate random progress-id */
uuid = "";
for (i = 0; i < 32; i++) {
uuid += Math.floor(Math.random() * 16).toString(16);
}
/* patch the form-action tag to include the progress-id */
document.getElementById("upload").action="/upload.php?" + uuid;
/* call the progress-updater every 1000ms */
interval = window.setInterval(
function () {
fetch(uuid);
},
1000
);
}
</script>
Now I only have to commit this code to SVN and make a pre-release :)
Trackbacks
Use the following link to trackback from your own site:
http://blog.lighttpd.net/articles/trackback/1887
-
Have you ever been annoyed about the fact that uploading files via the web browser usually lacks any kind of visual feedback how far the upload has progressed already? Well, worry no more - Jan has just added that functionality via mod_uploadprogr...
Comments
-
great! doing svn up each few minutes, can't wait for your commit! ;))
-
Yay! This is great. I like the straight-forwardness (is that a word?) We will definitely be making use of this.
-
That's absolutely fantastic, thanks so much. Been waiting and hoping this would re-appear. Any idea when the pre-release might be available? Or, dare I ask, the general release?
-
Great!!!! I'm waiting for it.....
-
I trying to test this module, but req.open("GET", "/progress", 1); return 404 error code What's wrong?
-
Sweetness!!!!!!!!!! Any clues on how to test it out??
-
Thank YOU! :D
-
And how to get it?...
-
Boom, make sure you aren't rewriting your url or passing it to fastcgi.
-
I'd like to try this out, but I can't find the source in svn. Is it in the lighttpd-merge-1.4.x branch?