Html5 finally solves an age old problem of being able to upload files while also showing the upload progress. Today most websites use Flash Player to achieve this functionality. Some websites continue to use the Html
Notice in the images above the following pieces of information made available to the user:
Notice that the
The first line of code in the method is doing something you've not seen or done before. Essentially, once you have a reference to the
In the second line of this method you'll see another object (
Code listing 4, below shows you an example of how you would create an instance of a
Going back to
Code Listing 3, you'll notice we've subscribed to a few events of the XMLHttpRequest object. In particular, pay attention to the first line after the event listners comment in the code.
The code listing above is pretty self explanatory so there is nothing much to say here.
<form> with enctype=multipart/form-data,
but with modification on the server side to enable showing users the upload progress. Essentially, what you need to do is hook into the server’s byte stream while it is receiving a file so you know how many bytes you’ve received and somehow convey that information back to the client browser, while it is still in the process of uploading the file. This solution works extremely well and is not fraught with the issues Flash Player causes (especially for large files). However it is fairly complicated and not for the faint of heart because you are essentially taking over the entire server side processing (when you tap into the byte stream) and that includes implementing the
multipart/form-data
protocol on the server side, along with a bunch of other things.
Uploading files using Html5
The XMLHttpRequest object has gotten a facelift in the Html5 specifications. Specifically the XMLHttpRequest Level 2 specification (currently the latest version) that has included the following new features:- Handling of byte streams such as File, Blob and FormData objects for uploading and downloading
- Progress events during uploading and downloading
- Cross-origin requests
- Allow making anonymous request - that is not send HTTP Referer
- The ability to set a Timeout for the Request
In this post we’ll look more closely at #1 and #2. In particular, uploading of files using XMLHttpRequest and providing upload progress information to the end-user. Note that this solution does not require any change to the server side, at least insofar as handling the multipart/form-data protocol. So existing server side logic should remain unchanged, which makes adapting this technology that much easier.
Figure 1: Showing the File Upload screen -Upload just started
![Html5FileUpload2 Html5FileUpload2](https://i-blog.csdnimg.cn/blog_migrate/86b4d88f4b209f9101ecb5d1297ca84d.jpeg)
Figure 2: Showing the File Upload screen with upload completed.
- Information on the file that has been selected such as
- File Name
- File Size
- Mime Type
- A Progress bar with percent complete
- The upload speed or upload bandwidth
- The approximate time remaining
- The bytes uploaded thus far
- A response from the server side (the organge box)
Html5 Progress Event
As per the Html5 Progress Events spec, the Html5 progress event provides the following information relevant to this conversationtotal
- Total bytes being transferredloaded
- Bytes uploaded thus farlengthComputable
- Specifies if the total size of the data/file being uploaded is known
Html5 Progress Event - What it should have been
Considering that those who go down the route of providing upload progress information to the end user will require to show all of the other information to the end user as well, the Html5 Progress Event specifications should have accounted for this need as well, as it would be fairly simple for browser vendors to provide these additional pieces of information each time the progress event is raised. So I propose that the progress event should be modified to the following:total
- Total bytes being transferredloaded
- Bytes uploaded thus farlengthComputable
- Specifies if the total size of the data/file being uploaded is knowntransferSpeed
as along
timeRemaining
as a JavaScriptDate
object
Html5 Upload using XMLHttpRequest
I've provided a Uploading files using Html5 with Progress indication demo for those who want to jump right to it. All of the JavaScript code required is in the page. However, because the demo is a real world demo there are a number of CSS styles in use, and the layout of the page (the Html) is fairly complex. In this article we work with a minimalistic version of the Html and JavaScript so as to keep things simple and understandable.Browser Support for this Feature
At the time of this writing only the following browsers support this feature- Firefox 4.0 beta 6
- Chrome 6
- Safari 5.02
Let's get started
The entire code listing for the minimalistic but functional implementation can be found in Code Listing 6. Each aspect of the minimalistic Html/JavaScript is explained in detail in the rest of this article. Below, is a very simple Html form. This Html is no different then the Html you'd use to do a regular Html/HTTP file upload you'd use today (Html4 and pretty much any previous version of Html).<!DOCTYPE html>
<html> <head> <title>Upload Files using XMLHttpRequest - Minimal</title> </head> <body> <form id="form1" enctype="multipart/form-data" method="post" action="Upload.aspx"> <div class="row"> <label for="fileToUpload">Select a File to Upload</label><br /> <input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/> </div> <div id="fileName"></div> <div id="fileSize"></div> <div id="fileType"></div> <div class="row"> <input type="button" onclick="uploadFile()" value="Upload" /> </div> <div id="progressNumber"></div> </form> </body> </html>
Code Listing 1: The bare minimum Html Page
<input type="file"/>
element has the
onchange
event assigned to a JavaScript method called
fileSelected()
. So essentially, each time someone selects a file by browsing to a file on their local system, this event is raised. The
fileSelected()
JavaScript method looks like the following.
function fileSelected() {
var file = document.getElementById('fileToUpload').files[0];
if (file) {
var fileSize = 0;
if (file.size > 1024 * 1024)
fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
else fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB'; document.getElementById('fileName').innerHTML = 'Name: ' + file.name; document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize; document.getElementById('fileType').innerHTML = 'Type: ' + file.type; } }
Code Listing 2: The fileSelected() JavaScript method
<input type="file"/>
element, you have access to what is called a
FileList
object which is new in Html5 and is part of the
File APIspecifications of Html 5. A
FileList
object is a collection of files. More specifically, it is a collection of
File
objects. A
File
object has the following properties.
name
- The name of the file (excluding any path)type
- The MIME type of the file (in lower case)size
- The size of the file in bytes
FileReader
object. We won't be dealing with the
FileReader
in this example, so I'm not going to overwhelm you with yet another new object. We have a couple of new objects to discuss yet. You could use the information the
File
object provides you to say, prevent users from uploading files larger than the certain size. Or you could use the
type
property (MIME type) to figure out the type of file the user is attempting to upload and change the behavior of your form (on the client side of course). The above JavaScript method populates the grey box with grey text (in
Figures 1 & 2 above) with the information the
File
object provides us about the selected file. The file size is in bytes, so there is logic in the method to convert the size into a human readable form, such as 15.65MB instead of 15795748864 bytes. After the user has selected a file she'll want to upload the file and so she's going to click on the
Upload button. Notice in the code listing for the Html form (
Code Listing 1) that the Upload button has its
onclick
event assigned to the
uploadFile()
JavaScript method.
function uploadFile() {
var xhr = new XMLHttpRequest();
var fd = document.getElementById('form1').getFormData();
/* event listners */
xhr.upload.addEventListener("progress", uploadProgress, false); xhr.addEventListener("load", uploadComplete, false); xhr.addEventListener("error", uploadFailed, false); xhr.addEventListener("abort", uploadCanceled, false); /* Be sure to change the url below to the url of your upload server side script */ xhr.open("POST", "UploadMinimal.aspx"); xhr.send(fd); }
Code Listing 3: The uploadFile() JavaScript method
FormData
) that we've never seen nor used before. You're not really seeing it, but we do get a reference to it using the
getFormData()
method of the
<form>
element. A
FormData
object is similar to a dictionary, a collection of name/value pairs. Where the name part is the name of a form field (as defined in the Html page) and the value is the value of this field. The value part can be a string, number or even a
File
object, as you can see in
Code listing 4. So when you call the
getFormData()
method on the form you get a reference to a FormData object that holds a collection of name/value pairs of that form. You can use this reference as the information you want to send to the server side script. This makes it really simple to submit the entire form. Now you could create an instance of a
FormData
object manually and send that to the server or you could add additional information to the
FormData
before sending it to the server side script.
A note about FormData
Note that as if this writing Chrome 6 supports uploading files using the new API but does not support thegetFormDate()
method. It does however, support the
FormData
object. So the full code listing of the bare minimal code in
Code Listing 6 manually creates a
FormData
instance as discussed below. Another way to instantiate an instance of FormData is to pass in a reference to a form element. like so:
var fd = new FormData(document.getElementById('form1'));
This constructor has the advantage of populating the
FormData
instance with all the form's fields, instead of having to do it manually (similar to the
getFormData
method of the form element discussed earlier. At the time of this writing, on Firefox supports this method.
FormData
object, assign some arbitrary fields and their values, including a reference to a
File
object (the file selected by the user using the
<&tl;file type="file">
element.
var fd = new FormData();
fd.append("author", "Shiv Kumar");
fd.append("name", "Html 5 File API/FormData"); fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
Code Listing 4: Manually creating a FormData instance
xhr.upload.addEventListener("progress", uploadProgress, false);
The progress event we subscribe to is not that of the XMLHttpRequest instance, but rather the
upload
property of the XMLHttpRequest instance, which is an
XMLHttpRequestUpload type that is really an event target that has a
progress
event we can subscribe to in order to get progress information on the upload that is taking place. We don't have to worry about this object. Just remember, when using XMLHttpRequest for uploading data to the server, you must subscribe to its
upload
property's
progress
event.
A note about Progress Events
The XMLHttpRequest object does have a progress event of it's own and you'll subscribe to that event when you download data from the server (which we are not covering here).function uploadProgress(evt) {
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%';
}
else {
document.getElementById('progressNumber').innerHTML = 'unable to compute'; } } function uploadComplete(evt) { /* This event is raised when the server send back a response */ alert(evt.target.responseText); } function uploadFailed(evt) { alert("There was an error attempting to upload the file."); } function uploadCanceled(evt) { alert("The upload has been canceled by the user or the browser dropped the connection."); }
Code Listing 5: The implementation of the various event handlers
The Minimalistic Solution
The Code listing below is the entire Html page including the JavaScript and Html required to get a bear minimum File upload with progress indicator working. I've intentionally kept it simple so if you want to do your own layout and information display you can start with this and expand it. Html5 also introduces aprogress
element that can be used to show progress. The
progress
element has
max
and
value
and so it makes it really simple to show progress. However, at the time of this writing, only Chrome 6 supports this element so I've not used it in the minimalistic solution.
Change the Url to the server side script
Be sure to change the url to point to the url of your server side script that handles file uploads. In the code listing below, it is UploadMinimal.aspx in theuploadFile()
method:
xhr.open("POST", "UploadMinimal.aspx");
<!DOCTYPE html>
<html> <head> <title>Upload Files using XMLHttpRequest - Minimal</title> <script type="text/javascript"> function fileSelected() { var file = document.getElementById('fileToUpload').files[0]; if (file) { var fileSize = 0; if (file.size > 1024 * 1024) fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB'; else fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB'; document.getElementById('fileName').innerHTML = 'Name: ' + file.name; document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize; document.getElementById('fileType').innerHTML = 'Type: ' + file.type; } } function uploadFile() { var fd = new FormData(); fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]); var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", uploadProgress, false); xhr.addEventListener("load", uploadComplete, false); xhr.addEventListener("error", uploadFailed, false); xhr.addEventListener("abort", uploadCanceled, false); xhr.open("POST", "UploadMinimal.aspx"); xhr.send(fd); } function uploadProgress(evt) { if (evt.lengthComputable) { var percentComplete = Math.round(evt.loaded * 100 / evt.total); document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%'; } else { document.getElementById('progressNumber').innerHTML = 'unable to compute'; } } function uploadComplete(evt) { /* This event is raised when the server send back a response */ alert(evt.target.responseText); } function uploadFailed(evt) { alert("There was an error attempting to upload the file."); } function uploadCanceled(evt) { alert("The upload has been canceled by the user or the browser dropped the connection."); } </script> </head> <body> <form id="form1" enctype="multipart/form-data" method="post" action="Upload.aspx"> <div class="row"> <label for="fileToUpload">Select a File to Upload</label><br /> <input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/> </div> <div id="fileName"></div> <div id="fileSize"></div> <div id="fileType"></div> <div class="row"> <input type="button" onclick="uploadFile()" value="Upload" /> </div> <div id="progressNumber"></div> </form> </body> </html>
Code Listing 6: The Complete but minimalistic code listing
Well, that pretty much covers the minimalistic version of the new Html5 feature. Getting at the other information that you see in Figure2 is mathematical really. It is quite a bit of extra work to not only get at the information, but to display and animate etc. For instance to get the rate of upload (the upload speed). We do the following: 1. in theuploadProgress(evt)
event, should store the
evt.loaded
and
evt.total
in global variables. 2. We set up a timer event to fire every second. 3. In the timer callback we get the difference of the number of bytes transfered between now and the last time the callback was called (so 1 second ago). 4. That gives us the number of bytes per second. Which is the upload speed. Note that in the demo I set up the timer to fire every 500 milliseconds to get more granularity. As a result the difference between the number of bytes is doubled since the number of bytes is really the number of bytes transferred in half a second. I won't go into how to find the time remaining, but it's all there in the demo. Do a "view source" to see the code in the demo's html page. I hope you found this article helpful.
Comments
Kent Davis26th January, 2011
Shiv Kumar26th January, 2011
Kent,
Did you try uploading using the demo at Uploading files using Html5 with Progress indication?
Also make sure you're using a browser that supports this feature.
What error do you see? If you need the script, you can simply do a view source on the demo page and take the complete script from there.
Did you try uploading using the demo at Uploading files using Html5 with Progress indication?
Also make sure you're using a browser that supports this feature.
What error do you see? If you need the script, you can simply do a view source on the demo page and take the complete script from there.
Kent Davis28th January, 2011
Hi there
Yes. I use Safari 5.0.3. Since I am not familiar with .aspx. I use php.
I changed the path from
I copy all of your codes in "Upload.php".
What is it that I am missing? Can I use PHP? and also I am using GoDaddy.
Thanks
Kent
Yes. I use Safari 5.0.3. Since I am not familiar with .aspx. I use php.
I changed the path from
I copy all of your codes in "Upload.php".
What is it that I am missing? Can I use PHP? and also I am using GoDaddy.
Thanks
Kent
Shiv Kumar28th January, 2011
Hi Kent, well the issue is that on the PHP side you need to support the multipart/form-data protocol. This is typically when receiving large uploaded files on the server side.
By default when you submit a form the browser uses application/x-www-form-urlencoded protocol (or the enctype attribute of the html >form< tag.
Now for small files (smaller than 48K) you can change the enctype attribute of the form or remove it entirely and you php side should work. But for large files, your php side will need to support the multipart/form-data protocol. And yes, php does support this, so there is a way to do it, but I'm not a php person so I can't help you there.
Nonetheless, your issue is a server side (php in this case) related issue and not a html 5 or browser related issue.
By default when you submit a form the browser uses application/x-www-form-urlencoded protocol (or the enctype attribute of the html >form< tag.
Now for small files (smaller than 48K) you can change the enctype attribute of the form or remove it entirely and you php side should work. But for large files, your php side will need to support the multipart/form-data protocol. And yes, php does support this, so there is a way to do it, but I'm not a php person so I can't help you there.
Nonetheless, your issue is a server side (php in this case) related issue and not a html 5 or browser related issue.
Kent Davis28th January, 2011
Would you like fix for HTML and/or PHP and send me file document (Upload file) something?
mac4kent@gmail.com
mac4kent@gmail.com
Shiv Kumar28th January, 2011
Kent,
It's not something that needs to be fixed on the client side. Your php code needs to be "fixed". That it is need to account for multipart/form-data.
A regular php file upload script (that handles multipart/form-data will work. For example, take a look at this
php - file upload
It's not something that needs to be fixed on the client side. Your php code needs to be "fixed". That it is need to account for multipart/form-data.
A regular php file upload script (that handles multipart/form-data will work. For example, take a look at this
php - file upload
Kent Davis28th January, 2011
Sigh I can't find download simply script for upload.
not matter support on script for html.
I need get document complete and easy to click upload file.
not matter support on script for html.
I need get document complete and easy to click upload file.
Eric P3rd February, 2011
Great article...and very well written! Thanks for sharing. I'm especially impressed with the simplicity of your coding example. It's a positive that you are only referencing "Upload.aspx" and not getting into the server side processing part, because that has nothing to do with the scope of HTML5 functionality.
Anyway, I would love to see you expand the article/example to include cross site requests( https://wiki.mozilla.org/Cross_Site_XMLHttpRequest). I'm working on an app that submits to another website which I don't have control of the code (other than the ability to post uploads, and put content ... including a crossdomain.xml file).
Also, while I'm making requests :), I would also like to see your code interpretation of a clean interface for selecting and uploading multiple files, utilizing the HTML5 multiple file input functionality.
Keep up the great work!
Anyway, I would love to see you expand the article/example to include cross site requests( https://wiki.mozilla.org/Cross_Site_XMLHttpRequest). I'm working on an app that submits to another website which I don't have control of the code (other than the ability to post uploads, and put content ... including a crossdomain.xml file).
Also, while I'm making requests :), I would also like to see your code interpretation of a clean interface for selecting and uploading multiple files, utilizing the HTML5 multiple file input functionality.
Keep up the great work!
Easton Harvey17th February, 2011
One other suggestion I would make would be to move the:
var uploadResponse = document.getElementById('uploadResponse');
uploadResponse.innerHTML = ' Please wait...';
uploadResponse.style.display = 'block';
Up to right after the submit post aka:
intervalTimer = setInterval(updateTransferSpeed, 500);
Otherwise it doesn't get fired.
Like Eric, I would love to see any implementation you may have for multi files.
Thank you and keep it up!
var uploadResponse = document.getElementById('uploadResponse');
uploadResponse.innerHTML = ' Please wait...';
uploadResponse.style.display = 'block';
Up to right after the submit post aka:
intervalTimer = setInterval(updateTransferSpeed, 500);
Otherwise it doesn't get fired.
Like Eric, I would love to see any implementation you may have for multi files.
Thank you and keep it up!
Easton Harvey17th February, 2011
I love what you've done. Thank you for sharing.
For those reading this, a easy ASP.NET codebehind implementation would be to post to a Generic Hander:
public void ProcessRequest (HttpContext context) {
//Capture File From Post
HttpPostedFile file = context.Request.Files["fileToUpload"];
//Optional: Convert to File to binary if you need to forward it to a video encoding service like Panda Stream
//BinaryReader b = new BinaryReader(file.InputStream);
//byte[] binData = b.ReadBytes(file.ContentLength);
b.Close();
//Or just save it locally
file.SaveAs("dir");
string result = "File Saved Successfully";
context.Response.ContentType = "text/plain";
context.Response.Write(result);
}
Ask me if you have any questions :)
For those reading this, a easy ASP.NET codebehind implementation would be to post to a Generic Hander:
public void ProcessRequest (HttpContext context) {
//Capture File From Post
HttpPostedFile file = context.Request.Files["fileToUpload"];
//Optional: Convert to File to binary if you need to forward it to a video encoding service like Panda Stream
//BinaryReader b = new BinaryReader(file.InputStream);
//byte[] binData = b.ReadBytes(file.ContentLength);
b.Close();
//Or just save it locally
file.SaveAs("dir");
string result = "File Saved Successfully";
context.Response.ContentType = "text/plain";
context.Response.Write(result);
}
Ask me if you have any questions :)
Shiv Kumar17th February, 2011
Hey Easton, can you explain what you mean by "Otherwise it doesn't get fired." in your first comment? I'm not sure I understand what you mean by that.
The uploadResponse div is used to show the response from the server after the file has been received so putting it right after setInterval doesn't make sense since that would make it visible as soon as you start uploading.
Have you tried the demo app (http://exposureroom.biz/upload.aspx), if so, do you see this behavior there?
The uploadResponse div is used to show the response from the server after the file has been received so putting it right after setInterval doesn't make sense since that would make it visible as soon as you start uploading.
Have you tried the demo app (http://exposureroom.biz/upload.aspx), if so, do you see this behavior there?
Easton Harvey19th February, 2011
Shiv,
I understand what you are doing, however what I am trying to explain is that the "Please Wait" is never shown/seen. I just moved it up to where i described and it works great :)
I understand what you are doing, however what I am trying to explain is that the "Please Wait" is never shown/seen. I just moved it up to where i described and it works great :)
Shiv Kumar21st February, 2011
Easton, I see. I'll take a look at it once again. Thanks for the heads up.
Rupert Paget28th June, 2011
Hi,
I tested quite a few methods for uploading files, and each had their drawbacks. In the end I chose yours, as I thought it was definitely the best. Worked brilliantly. I just had to delete the line:
document.getElementById('progressInfo').style.display = 'none';
as the element progressInfo did not exist. Then I get the "Please Wait" message.
Thanks
I tested quite a few methods for uploading files, and each had their drawbacks. In the end I chose yours, as I thought it was definitely the best. Worked brilliantly. I just had to delete the line:
document.getElementById('progressInfo').style.display = 'none';
as the element progressInfo did not exist. Then I get the "Please Wait" message.
Thanks
Kevin UK11th July, 2011
Hi,
Is there any fallback code to support IE (as in just submit the form and not worrying about displaying a progress bar?)
Also when I try the line:
var fd = document.getElementById('form1').getFormData();
Then I get the error message:
Uncaught TypeError: Object #
Is there any fallback code to support IE (as in just submit the form and not worrying about displaying a progress bar?)
Also when I try the line:
var fd = document.getElementById('form1').getFormData();
Then I get the error message:
Uncaught TypeError: Object #
Shiv Kumar11th July, 2011
Kevin,
Feel free to code you own fallback route. It defeates the purpose of this post since this post is about Html 5 file upload with progress.
As regards the error, please make sure your browser support Html 5 File Upload.
Use the test site with your browser. IF it doesn't work then your browser is the problem.
Feel free to code you own fallback route. It defeates the purpose of this post since this post is about Html 5 file upload with progress.
As regards the error, please make sure your browser support Html 5 File Upload.
Use the test site with your browser. IF it doesn't work then your browser is the problem.
Mayur Prajapati13th July, 2011
Can this script handle uploading multiple files? Can I just append "multiple" to the input tag?
Nikhil Verma14th July, 2011
Shiv,
u showed a nice example using HTML5 specs, but i just have one question as i am developing in php and not aspx, do i need to change the file name to abc.php in the XHR.open() statement. Will that solve the purpose? Please help.
u showed a nice example using HTML5 specs, but i just have one question as i am developing in php and not aspx, do i need to change the file name to abc.php in the XHR.open() statement. Will that solve the purpose? Please help.
Shiv Kumar14th July, 2011
Nikhil,
Yes, if your PHP page is abc.php, then yes. However, make sure your php page canactually handle a File Upload (there is special code required on the server side to do that, you need to support the multipart/form-data protocol. This is typically when receiving large uploaded files on the server side.
).
Please take a look at my answers to Kent Davis above.
Yes, if your PHP page is abc.php, then yes. However, make sure your php page canactually handle a File Upload (there is special code required on the server side to do that, you need to support the multipart/form-data protocol. This is typically when receiving large uploaded files on the server side.
).
Please take a look at my answers to Kent Davis above.
Shiv Kumar14th July, 2011
Mayur,
There will be two things that will need to be adjusted. The first is of course the "multiple" attrubute for the file input tag as you mentioned. Now if you're trying to access these files (their names etc.) on the client side you'll need to iterate over the "files" collection on the input element.
Something like:
for (var i = 0; i
// input.files[i] is a file object
}
The variable "file" is input element as per the example code above.
If your server side is php, I believe you need to name the input element (in the Html side) such that it has brackets like so:
name="fileToUpload[]"
instead of what we have now
name="fileToUpload"
There will be two things that will need to be adjusted. The first is of course the "multiple" attrubute for the file input tag as you mentioned. Now if you're trying to access these files (their names etc.) on the client side you'll need to iterate over the "files" collection on the input element.
Something like:
for (var i = 0; i
// input.files[i] is a file object
}
The variable "file" is input element as per the example code above.
If your server side is php, I believe you need to name the input element (in the Html side) such that it has brackets like so:
name="fileToUpload[]"
instead of what we have now
name="fileToUpload"
Jose Calderon14th July, 2011
Thank you Easton Harvey.
Good Stuff.
Good Stuff.
lele long25th July, 2011
Firefox 4 change the getFormData API(see https://github.com/lento/spam/issues/18#issuecomment-934575),so alter the code to this:
var fd = new FormData(document.getElementById('revisioned_form'));
var fd = new FormData(document.getElementById('revisioned_form'));
Shiv Kumar26th July, 2011
Lele,
This use of FormData instead of the method getFormData() method has already been mentioned in the note: A note about FormData under code listing 3
This use of FormData instead of the method getFormData() method has already been mentioned in the note: A note about FormData under code listing 3
Igor Alves21st August, 2011
Hi,
first of all, it is a good code thks for share.
I have a question about that.
I have a function says blah() that id like to call after upload is completed.
I didnt find the exact place where i should put the function. I've tried after progress bar if (percentComplete == 100) {..}. But doens work.
What should i do? tnks
first of all, it is a good code thks for share.
I have a question about that.
I have a function says blah() that id like to call after upload is completed.
I didnt find the exact place where i should put the function. I've tried after progress bar if (percentComplete == 100) {..}. But doens work.
What should i do? tnks
Shiv Kumar24th August, 2011
Hi Igor,
In Code list 6 above, the method "uploadComplete" has been tied to the "load" event. So you could call your method from within the uploadComplete method to get the behavior you want.
In Code list 6 above, the method "uploadComplete" has been tied to the "load" event. So you could call your method from within the uploadComplete method to get the behavior you want.
Mithun MOhan20th October, 2011
Hi Shiv,
Nice tutorial . How do i cancel the upload .Could you share your points.
Thanks
Nice tutorial . How do i cancel the upload .Could you share your points.
Thanks
Shiv Kumar20th October, 2011
Hi Mithun,
the xhr.upload (as per code listing 3 and 6 above) is really an instance of type XMLHttpRequestUpload. This class has an abort() method that you can call to abort (or cancel) the upload.
the xhr.upload (as per code listing 3 and 6 above) is really an instance of type XMLHttpRequestUpload. This class has an abort() method that you can call to abort (or cancel) the upload.
craig beswetherick14th November, 2011
Hi there - good article, I will be using this in future!
I would like to ask what problems you can experience loading large files using Flash however. Just sounds like poor coding blamed on the tech to me :-)
However great work - thanks!
I would like to ask what problems you can experience loading large files using Flash however. Just sounds like poor coding blamed on the tech to me :-)
However great work - thanks!
Dripple D.14th November, 2011
Hi,
Is there a way to manage throughput the same way ?
Thanks.
Dripple
Is there a way to manage throughput the same way ?
Thanks.
Dripple
Shiv Kumar14th November, 2011
Hi Craig,
There are quite a few problems one encounters with uploading large files with Flash. In fact I have logged a few bugs with Adobe myself as we used to use Flash for uploading large video files at http://exposureroom.com. We've since moved to using pure Html with our own progress indication mechanism that works flawlessly.
I'm afraid I don't remember the details anymore but the kinds of problems our users encountered were really hard to track and figure out. Finally, you always got only one error code (no matter what the issue was) from the Flash player and that wasn't helpful either. Long story short, it was too much of a headache to continue to use/support and Adobe kept deffering fixing the bugs to next release which never materialized.
There are quite a few problems one encounters with uploading large files with Flash. In fact I have logged a few bugs with Adobe myself as we used to use Flash for uploading large video files at http://exposureroom.com. We've since moved to using pure Html with our own progress indication mechanism that works flawlessly.
I'm afraid I don't remember the details anymore but the kinds of problems our users encountered were really hard to track and figure out. Finally, you always got only one error code (no matter what the issue was) from the Flash player and that wasn't helpful either. Long story short, it was too much of a headache to continue to use/support and Adobe kept deffering fixing the bugs to next release which never materialized.
Shiv Kumar14th November, 2011
Dripple,
Any throughput related issues can/should be managed on the server side.
Any throughput related issues can/should be managed on the server side.
Vinoth Kumar16th November, 2011
Thanks for sharing a nice script. :)
John Agricola20th November, 2011
Excellent Stuff but hard to understand at the beginning ;)
Srdjan Radic24th November, 2011
This is great way to improve my image upload form.
Thanks.
Thanks.
Kshyhoo10th December, 2011
Would like to subscribe this website with RSS :)
Shiv Kumar12th December, 2011
Kshyhoo,
The url for the RSS Feed is:
http://www.matlus.com/feed/
The url for the RSS Feed is:
http://www.matlus.com/feed/
Vishal Hatiskar17th January, 2012
hii Shiv Kumar this is great artical...but why the progress event is not working in mozilla firefox 9.0.1 browser which is latest...i tried above demo also it is not working as no progress bar is shown..so what is solution for that...thank you...
Shiv Kumar17th January, 2012
Vishal, I just tested my sample website (link in the article) using Firefox 9.0.1 and it works as expected.
jibin mathew15th February, 2012
How can i read the json Data returned form the server for the POST method on the uploadComplete function and display contents in the Json data (satus, ImageUrl etc)
Shiv Kumar15th February, 2012
Jibin,
Take a look at the uploadComplete event in code listing 6 above. The evt parameter contains the response. More specifically, evt.target.responseText contains the response from the server. This response could be in any format such as xml, JSON or just plain text).
You could also tap into evt.target.responseType which is the MIME type of the response and act accordingly. That is, if the responseType is "json" then you could use the JSON object's (defined in ECMAScript) parse function to retrieve the JSON returned by the server.
Take a look at the uploadComplete event in code listing 6 above. The evt parameter contains the response. More specifically, evt.target.responseText contains the response from the server. This response could be in any format such as xml, JSON or just plain text).
You could also tap into evt.target.responseType which is the MIME type of the response and act accordingly. That is, if the responseType is "json" then you could use the JSON object's (defined in ECMAScript) parse function to retrieve the JSON returned by the server.
Rohit Chowdhary19th February, 2012
Hi Shiv
Thank For This Article
integrated on joomla+virtuemart successfully
you saved my day
hope it works on IE
Thank For This Article
integrated on joomla+virtuemart successfully
you saved my day
hope it works on IE
sandy yadav27th February, 2012
Hi Shiv,
i tried your demo and seems like it works accurately only on bmp files, for jpg's it's instantly shows 100% in chrome and not showing any progress in firefox, any ideas?
i tried your demo and seems like it works accurately only on bmp files, for jpg's it's instantly shows 100% in chrome and not showing any progress in firefox, any ideas?
Shiv Kumar27th February, 2012
Sandy,
Have you tried the test site I provide (link is in the article above)? Jpg files are generally smaller than bmp files and I think what is happening with you is that it takes no time to upload the jpeg file as compared to the bmp file and that's proably why you think it doesn't work for jpeg files.
It works just fine for me (test it against the test site) no matter what file I upload.
Have you tried the test site I provide (link is in the article above)? Jpg files are generally smaller than bmp files and I think what is happening with you is that it takes no time to upload the jpeg file as compared to the bmp file and that's proably why you think it doesn't work for jpeg files.
It works just fine for me (test it against the test site) no matter what file I upload.
Gurame Rame28th February, 2012
Well done. I tried the upload test link too.
Works great.
Thank's for sharing.
Works great.
Thank's for sharing.
Rafal Karczewski14th March, 2012
Shiv,
Great article, very helpful.
Thanks !
Great article, very helpful.
Thanks !
Umair Peracha16th March, 2012
hi,
I have tried this example and it works like a charm. I am using ASP.NET MVC 3 at the server end and files smaller than 20 MB are being uploaded but as I try to upload a larger file the java script throws and error "There was an error attempting to upload the file". The server side code never gets hit. Any idea why this is happening?
I have tried this example and it works like a charm. I am using ASP.NET MVC 3 at the server end and files smaller than 20 MB are being uploaded but as I try to upload a larger file the java script throws and error "There was an error attempting to upload the file". The server side code never gets hit. Any idea why this is happening?
Shiv Kumar16th March, 2012
Umair,
This is an ASP.NET set up specific problem I believe. Have you modified any web.config or applicationHost.config file settings related to request length? If not, you'll need to make some modifications.
In your web.config you'll need to set the maxRequestLength to a large number (The size is in Kb)
HttpRuntimeSection.MaxRequestLength Property.
You'll also need to set the maxAllowedContentLength attribute of the requestFiltering.requestLimits node under system.webserver (IIS 7 and above will neede this). However, before you can do that (and make it work), you'll need to modify the applicationHost.config file on your %windir%\System32\inetsrv\config folder.
Take a look at this forum thread
Changing maxAllowedContentLength
This is an ASP.NET set up specific problem I believe. Have you modified any web.config or applicationHost.config file settings related to request length? If not, you'll need to make some modifications.
In your web.config you'll need to set the maxRequestLength to a large number (The size is in Kb)
HttpRuntimeSection.MaxRequestLength Property.
You'll also need to set the maxAllowedContentLength attribute of the requestFiltering.requestLimits node under system.webserver (IIS 7 and above will neede this). However, before you can do that (and make it work), you'll need to modify the applicationHost.config file on your %windir%\System32\inetsrv\config folder.
Take a look at this forum thread
Changing maxAllowedContentLength
King Wilder26th March, 2012
You saved me! I was using the Telerik for MVC Extensions and while they work, I had files well over 100MB to upload and they just wouldn't work with files that large.
I just changed the maxRequestLength value to 1024000, and the requestLimits maxAllowedContentLength to 1024000000.
Great job!
I just changed the maxRequestLength value to 1024000, and the requestLimits maxAllowedContentLength to 1024000000.
Great job!
Ry Lowry31st March, 2012
This demo helped me get started with HTML5 drag/drop file uploads, but now I'm stumped on something new. Is it possible to drag and drop files into a form, and then perform a typical form submission? Basically, I want to drag and drop files into a form, and then submit the files without any ajax. Is it possible to append files from a FileList to an existing form, or is it only possible to create a new FormData object, and submit it with an XMLHttpRequest?
Harry Hamill21st January, 2013
This is excellent. Furthermore in following what was going on here I think now have a lot more understanding of the uploading process. Thanks!
Lee Blevins15th June, 2013
I've read a lot of code examples and tutorials on the internet and this is without a doubt, the best written one I've seen. The key to the success of this one is the "keep it simple" idea and the quality of the writing.
So many I've seen are overly complex and obscure the objective.
Thank you for writing well and keeping it simple.
So many I've seen are overly complex and obscure the objective.
Thank you for writing well and keeping it simple.
Suraj Shrestha15th September, 2015
This post was a great help to cope the issue I faced.
However some issues I'm still facing:
I want to post back after the button is clicked i.e. I'm using
Can you please provide me suggestion for the issue I'm facing?
Thank you.
However some issues I'm still facing:
I want to post back after the button is clicked i.e. I'm using
Can you please provide me suggestion for the issue I'm facing?
Thank you.
Tarun Ghosh16th September, 2015
I believe the XMLHttpRequestUpload progress even is called multiple time. How frequently does the event handler function is called and is there any settings through which we can control that?
Alfred Nassim31st December, 2015
Hi Shiv,
In September 2010, you were kind enough to send me TMsMultipartParser.pas It worked fine with Delphi 7 :-)
Do you have anything similar that works with more recent versions of Delphi?
Kind regards,
Alfred
Melbourne
In September 2010, you were kind enough to send me TMsMultipartParser.pas It worked fine with Delphi 7 :-)
Do you have anything similar that works with more recent versions of Delphi?
Kind regards,
Alfred
Melbourne
Shiv Kumar5th January, 2016
Hi Alfred,
I'm afraid I don't use Delphi anymore and so I don't know what has changed in the ISAPI framework in Delphi since then.
The concept is still the same however. So maybe you or someone in the community can make the changes required?
I'm afraid I don't use Delphi anymore and so I don't know what has changed in the ISAPI framework in Delphi since then.
The concept is still the same however. So maybe you or someone in the community can make the changes required?
转载来源:http://www.matlus.com/html5-file-upload-with-progress/
<script language="javascript" type="text/javascript"> 2 3 function fileSelected() { 4 var file = document.getElementById('fileToUpload').files[0]; 5 var fileName = file.name; 6 var file_typename = fileName.substring(fileName.lastIndexOf('.'), fileName.length); 7 8 if (file_typename == '.xls') {//这里限定上传文件文件类型 9 if (file) { 10 11 $("#uploadFile").show(); 12 var fileSize = 0; 13 if (file.size > 1024 * 1024) 14 fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB'; 15 else 16 fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB'; 17 18 document.getElementById('fileName').innerHTML = '文件名: ' + file.name; 19 document.getElementById('fileSize').innerHTML = '大小: ' + fileSize; 20 document.getElementById('fileType').innerHTML = '类型: ' + file.type; 21 22 23 } 24 25 } 26 else { 27 28 $("#uploadFile").hide(); 29 document.getElementById('fileName').innerHTML = "<span style='color:Red'>错误提示:上传文件应该是.xls后缀而不应该是" + file_typename + ",请重新选择文件</span>" 30 document.getElementById('fileSize').innerHTML =""; 31 document.getElementById('fileType').innerHTML =""; 32 33 } 34 } 35 36 function uploadFile() { 37 var fd = new FormData(); 38 fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]); 39 var xhr = new XMLHttpRequest(); 40 xhr.upload.addEventListener("progress", uploadProgress, false); 41 xhr.addEventListener("load", uploadComplete, false); 42 xhr.addEventListener("error", uploadFailed, false); 43 xhr.addEventListener("abort", uploadCanceled, false); 44 xhr.open("POST", "/Goods/ToLead"); 45 xhr.send(fd); 46 } 47 48 function uploadProgress(evt) { 49 if (evt.lengthComputable) { 50 var percentComplete = Math.round(evt.loaded * 100 / evt.total); 51 $('#progressNumber').progressbar('setValue', percentComplete); 52 } 53 else { 54 document.getElementById('progressNumber').innerHTML = '无法计算'; 55 } 56 } 57 58 function uploadComplete(evt) { 59 /* 服务器返回数据*/ 60 var message = evt.target.responseText; 61 62 } 63 64 function uploadFailed(evt) { 65 alert("上传出错."); 66 } 67 68 function uploadCanceled(evt) { 69 alert("上传已由用户或浏览器取消删除连接."); 70 } 71 </script> 72 <div data-options="region:'center',title:'货品管理',iconCls:'icon-ok'"> 73 <div style="margin: 70px;"> 74 75 <div id="#DivUp"> 76 77 @using (Html.BeginForm("ToLead", "Goods", FormMethod.Post, new { enctype = "multipart/form-data", id = "form1" })) 78 { 79 <div class="row"> 80 <label for="file"> 81 <h5> 82 文件上传:</h5> 83 </label> 84 <input type="file" name="fileToUpload" id="fileToUpload" multiple="multiple" οnchange="fileSelected();" /> 85 <a id="uploadFile" style=" display:none" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-save'" οnclick="uploadFile()"> 86 上传并导入</a> 87 </div> 88 89 <div id="fileName" style="padding: 10px"> 90 </div> 91 <div id="fileSize" style="padding: 10px"> 92 </div> 93 <div id="fileType" style="padding: 10px"> 94 </div> 95 96 <div id="progressNumber" class="easyui-progressbar" style="width: 400px;"> 97 </div> 98 } 99 </div> 100 </div> 101 102 </div>
1 /// <summary> 2 /// 上传文件 3 /// </summary> 4 /// <param name="fileToUpload"></param> 5 /// <returns></returns> 6 [HttpPost] 7 [ValidateInput(false)] 8 public string ToLead(HttpPostedFileBase[] fileToUpload) 9 { 10 try 11 { 12 string FileUrl = string.Empty; 13 foreach (HttpPostedFileBase file in fileToUpload) 14 { 15 string path = System.IO.Path.Combine(Server.MapPath("~/FileUpLoad/Goods"), System.IO.Path.GetFileName(file.FileName)); 16 file.SaveAs(path); 17 FileUrl = path; 18 } 19 20 21 return "上传成功"; 22 } 23 24 catch { 25 26 return "上传失败"; 27 } 28 29 }
Would you like send me new file and I can work on script solve problem?