I have a file upload designed to handle multiple images. Each image has an id—based on the order in which the images were uploaded—that I want to send along with the post request. So I iterate through my fileSelect.files
and upload the image with an XMLHttpRequest
.
If I use xhr.open('POST', ajaxURL, false);
(with asynchronous
set to false
) there's no issue; my xhr.onload = function () {...};
correctly returns the server response for each uploaded image.
However, if I try using xhr.open('POST', ajaxURL, true);
(with asynchronous
set to true
), the handler gets confused and will only output information about the last file uploaded.
I think this might be caused by calling a new xhr.open('POST', ...);
for every iteration of the loop. Is there a good way to either make the handler work with asynchronous requests, or to append the form data in such a way that I only need to make one request? This is a problem because I want to make sure each upload has completed successfully.
My working javascript is
// image upload handler
$(fileSelect).change(function(){
// get the information we need to upload an image
var ajaxURL = $("#action").val();
var CSRFToken = document.getElementsByName('csrfmiddlewaretoken')[0].value;
var house_id = $("#house_id").val();
console.info("Uploading files to " + ajaxURL + " with using house_id=" + house_id + " and a csrf token value of " + CSRFToken);
// make an AJAX call to upload the image
uploadImage(this, ajaxURL, CSRFToken, house_id);
});
/**
* Upload each image file in the given fileSelect object
* via an AJAX request to the specified URL using the provided
* CSRF token. A house_id parameter must be provided for the database
* to organize image uploads by house.
*/
var uploadImage = function(fileSelect, ajaxURL, CSRFToken, house_id) {
// get the selected files from the input
var files = fileSelect.files;
// create the object resposible for handling the ajax request
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status === 200) {
alert(xhr.statusText + ": " + xhr.responseText)
} else {
alert("Oops! The file upload failed. Please try again.");
}
};
// loop through each of the selected files
for (var i = 0; i < files.length; i++) {
var file = files[i];
// check the file type
if (!file.type.match('image.*')) {
// if it's not an image -> alert user & dont upload
alert(file.name + " could not be added because it is of the wrong filetype.");
continue;
}
console.log("Uploading " + file.name + " . . .");
// create a new FormData object for our images
var formData = new FormData();
// append the current image and related values to our form data
formData.append('file', file);
formData.append('csrfmiddlewaretoken', CSRFToken);
formData.append('house_id', house_id);
formData.append('image_id', i);
// make the request and set a handler
xhr.open('POST', ajaxURL, false);
xhr.send(formData);
}
};