December 5, 2014 in HTML5, JavaScript

How to Asynchronously Upload Files Using HTML5 and Ajax

The HTML

Let’s examine our HTML form again:


<form id="upload" action="upload.php" method="POST" enctype="multipart/form-data">

<fieldset>
<legend>HTML File Upload</legend>

<input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="300000" />

<div>
	<label for="fileselect">Files to upload:</label>
	<input type="file" id="fileselect" name="fileselect[]" multiple="multiple" />
	<div id="filedrag">or drop files here</div>
</div>

<div id="submitbutton">
	<button type="submit">Upload Files</button>
</div>

</fieldset>

</form>

We’ll be uploading files to a PHP page, upload.php. The page will handle both the Ajax upload requests and standard form POSTs when the user clicks “Upload Files”.

Our JavaScript will ensure that only JPG images are uploaded which are smaller than 300,000 bytes — the value specified in MAX_FILE_SIZE.

The JavaScript

First, we require an additional line within our FileSelectHandler() function which is called when one or more files is chosen or dropped. Within our File loop, we’ll call an additional function — UploadFile():


// file selection
function FileSelectHandler(e) {

	// cancel event and hover styling
	FileDragHover(e);

	// fetch FileList object
	var files = e.target.files || e.dataTransfer.files;

	// process all File objects
	for (var i = 0, f; f = files[i]; i++) {
		ParseFile(f);
		UploadFile(f);
	}

}

File uploading requires the XMLHttpRequest2 object which is currently available in Firefox and Chrome. Before we make the Ajax call, we ensure an .upload() method is available and that we have a JPG with a file size less than the MAX_FILE_SIZE form value:


// upload JPEG files
function UploadFile(file) {

	var xhr = new XMLHttpRequest();
	if (xhr.upload && file.type == "image/jpeg" && file.size <= $id("MAX_FILE_SIZE").value) {

The XMLHttpRequest .open() method is set to POST data to upload.php, the action attribute of our upload form. In addition, we set an HTTP header to the file’s name and pass the File object to the .send() method:


		// start upload
		xhr.open("POST", $id("upload").action, true);
		xhr.setRequestHeader("X_FILENAME", file.name);
		xhr.send(file);

	}

}

The PHP

Our PHP file, upload.php, now checks for the X_FILENAME HTTP header to differentiate between Ajax requests and standard form POSTs:


<?php
$fn = (isset($_SERVER['HTTP_X_FILENAME']) ? $_SERVER['HTTP_X_FILENAME'] : false);

If a filename has been set, PHP can retrieve the posted data and output it to a new file in an ‘uploads’ folder. Amazingly, this can be achieved in a single line of code:


if ($fn) {

	// AJAX call
	file_put_contents(
		'uploads/' . $fn,
		file_get_contents('php://input')
	);
	echo "$fn uploaded";
	exit();
	
}

Standard HTML multipart/form-data posts can be handled using the usual PHP $_FILE functions:


else {

	// form submit
	$files = $_FILES['fileselect'];

	foreach ($files['error'] as $id => $err) {
		if ($err == UPLOAD_ERR_OK) {
			$fn = $files['name'][$id];
			move_uploaded_file(
				$files['tmp_name'][$id],
				'uploads/' . $fn
			);
			echo "<p>File $fn uploaded.</p>";
		}
	}

}

Source Link: http://www.sitepoint.com/html5-ajax-file-upload/

 




By browsing this website, you agree to our privacy policy.
I Agree