jQuery Upload Progress and AJAX file upload

AjaxJqueryFile UploadNginx

Ajax Problem Overview


It seems like I have not clearly communicated my problem. I need to send a file (using AJAX) and I need to get the upload progress of the file using the Nginx HttpUploadProgressModule. I need a good solution to this problem. I have tried with the jquery.uploadprogress plugin, but I am finding myself having to rewrite much of it to get it to work in all browsers and to send the file using AJAX.

All I need is the code to do this and it needs to work in all major browsers (Chrome, Safari, FireFox, and IE). It would be even better If I could get a solution that will handle multiple file uploads.

I am using the jquery.uploadprogress plugin to get the upload progress of a file from the NginxHttpUploadProgressModule. This is inside an iframe for a facebook application. It works in firefox, but it fails in chrome/safari.

When I open the console I get this.

Uncaught ReferenceError: progressFrame is not defined
jquery.uploadprogress.js:80

Any idea how I would fix that?

I would like to also send the file using AJAX when it is completed. How would I implement that?

EDIT:
I need this soon and it is important so I am going to put a 100 point bounty on this question. The first person to answer it will receive the 100 points.

EDIT 2:
Jake33 helped me solve the first problem. First person to leave a response with how to send the file with ajax too will receive the 100 points.

Ajax Solutions


Solution 1 - Ajax

Uploading files is actually possible with AJAX these days. Yes, AJAX, not some crappy AJAX wannabes like swf or java.

This example might help you out: https://webblocks.nl/tests/ajax/file-drag-drop.html

(It also includes the drag/drop interface but that's easily ignored.)

Basically what it comes down to is this:

<input id="files" type="file" />

<script>
document.getElementById('files').addEventListener('change', function(e) {
	var file = this.files[0];
	var xhr = new XMLHttpRequest();
	(xhr.upload || xhr).addEventListener('progress', function(e) {
		var done = e.position || e.loaded
		var total = e.totalSize || e.total;
		console.log('xhr progress: ' + Math.round(done/total*100) + '%');
	});
	xhr.addEventListener('load', function(e) {
		console.log('xhr upload complete', e, this.responseText);
	});
	xhr.open('post', '/URL-HERE', true);
	xhr.send(file);
});
</script>

(demo: http://jsfiddle.net/rudiedirkx/jzxmro8r/)

So basically what it comes down to is this =)

xhr.send(file);

Where file is typeof Blob: http://www.w3.org/TR/FileAPI/

Another (better IMO) way is to use FormData. This allows you to 1) name a file, like in a form and 2) send other stuff (files too), like in a form.

var fd = new FormData;
fd.append('photo1', file);
fd.append('photo2', file2);
fd.append('other_data', 'foo bar');
xhr.send(fd);

FormData makes the server code cleaner and more backward compatible (since the request now has the exact same format as normal forms).

All of it is not experimental, but very modern. Chrome 8+ and Firefox 4+ know what to do, but I don't know about any others.

This is how I handled the request (1 image per request) in PHP:

if ( isset($_FILES['file']) ) {
	$filename = basename($_FILES['file']['name']);
	$error = true;

	// Only upload if on my home win dev machine
	if ( isset($_SERVER['WINDIR']) ) {
		$path = 'uploads/'.$filename;
		$error = !move_uploaded_file($_FILES['file']['tmp_name'], $path);
	}

	$rsp = array(
		'error' => $error, // Used in JS
		'filename' => $filename,
		'filepath' => '/tests/uploads/' . $filename, // Web accessible
	);
	echo json_encode($rsp);
	exit;
}

Solution 2 - Ajax

Here are some options for using AJAX to upload files:

UPDATE: Here is a JQuery plug-in for Multiple File Uploading.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionConceited CodeView Question on Stackoverflow
Solution 1 - AjaxRudieView Answer on Stackoverflow
Solution 2 - Ajaxjmort253View Answer on Stackoverflow