Hi! So we saw how to download files.
Let's see now how we can upload files!
Uploading a file means sending it to a remote server.
In this example, we will just look at the simplest possible thing: uploading one single file.
Later on, in the course, course you will see how to upload multiple files, including form input fields and so on.
We've got a file selector here: an input type=file, and we will select one file.
For example, here, I'm selecting an mp3 song.
And as soon as the file has been selected, in this example, you see that the file is uploaded to a remote server.
So let's look at how we can get the file we selected and send it.
We attached to the file selector a change event listener, that will be called as soon as we select the file.
In this callback we create an XML HTTP request and we indicate that it's a POST request.
POST is used for sending data to a remote server.
We are using JSBin, and the upload.html.
You see, here, is the URL of a fake server.
We don't have a remote server ready in this example, however JSBin handles that and pretends that the server exists.
We created the request, indicated the method and the URL of the server.
Then, we will prepare an object that is a FormData object.
It's a container in which you can append files or append any sort of data.
And the data are key/value pairs.
Here I added an object called "file" with a value that is the file I have selected earlier using the file input type=file element.
And when I send the request, I pass the FormData object that contains the file.
And then, as soon as the send method is called, the browser will handle the upload in background.
And this may take some time.
So let's start again here... if I select a file, you see that it takes some time before it's uploaded.
And when the upload you see the "upload complete message" because when the upload is complete the browser will call to onload callback for your request.
And during the upload, it will call the xhr.upload.onprogress callback.
That's a function that works exactly like the xhr.onprogress callback we used for downloading.
So, it's just this ".upload" that you write before the "onprogress" here.
That's the only difference with monitoring progress with download.
And here you can see that the "upload complete" message appears.
If we want to send multiple files, we can append multiple files here.
That's all for this video! Bye! Bye!
Here is an example that uses a FormData object for uploading one or more files to an HTTP server.
Notice that the URL of the server is fake, so the request will fail. However, the simulation takes time, and it is interesting to see how it works.
Later on, we will show full examples of real working code with server-side PHP source, during the “File API, drag and drop and XHR2” lecture.
Source code of the example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>File upload with XMLHttpRequest level 2 and HTML5</title>
</head>
<body>
<h1>Example of XHR2 file upload</h1>
Choose a file and wait a little until it is uploaded (on a fake
server). A message should pop up once the file is uploaded 100%.
<p>
<input id="file" type="file" />
</p>
<script>
var fileInput = document.querySelector('#file');
fileInput.onchange = function() {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'upload.html'); // With FormData,
// POST is mandatory
xhr.onload = function() {
alert('Upload complete !');
};
var form = new FormData();
form.append('file', fileInput.files[0]);
// send the request
xhr.send(form);
};
</script>
</body>
</html>
Line 18: callback called when the user selects a file.
Lines 19-20: preparation of the XHR2 request.
Lines 27-30: a FormData object is created (this will contain the (MIME) multipart form-data which will be sent by the POST request).
Line 30: the request is sent, with the FormData object passed as a parameter (all data is sent).
Line 23: when the file is completely uploaded, the onload listener is called and an alert message is displayed.
Here is a more user-friendly example. It is basically the same, but this time, we'll monitor the progress of the upload using a method similar to that used for monitoring file downloads:
We use a <progress> element and its two attributes value and max.
We also bind an event handler to the progress event that an XMLHttpRequest will trigger. The event has two properties: loaded and total that respectively correspond to the number of bytes that have been uploaded, and to the total number of bytes we need to upload (i.e., the file size).
Here is the code of such an event listener:
xhr.upload.onprogress = function(e) {
progress.value = e.loaded; // number of bytes uploaded
progress.max = e.total; // total number of bytes in the file
};
Code from this example (nearly the same as previous example's code):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>HTML5 file upload with monitoring</title>
</head>
<body>
<h1>Example of XHR2 file upload, with progress bar</h1>
Choose a file and wait a little until it is uploaded (on a fake server).
<p>
<input id="file" type="file" />
<br/><br/>
<progress id="progress" value=0></progress>
<script>
var fileInput = document.querySelector('#file'),
progress = document.querySelector('#progress');
fileInput.onchange = function() {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'upload.html');
xhr.upload.onprogress = function(e) {
progress.value = e.loaded;
progress.max = e.total;
};
xhr.onload = function() {
alert('Upload complete!');
};
var form = new FormData();
form.append('file', fileInput.files[0]);
xhr.send(form);
};
</script>
</body>
</html>
The only difference between these two worked-examples is the onprogress listener which updates the progress bar's value and max attributes.