<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title>HTML 5 File Upload, comment envoyer des fichiers avec XMLHttpRequest</title>
	<style type="text/css">
/* barre de progression */
#uploadProgress{
	display: none;
}
.progressBar{
	border: 1px solid #777;
	width: 140px;
}
.progressBar > span{
	height: 6px;
	display: block;
	background-color: #80FF00;
}
/* style divers */
body{
	margin: 0;
	padding: 0;
	background-color: #f8f4ee;
	text-align: center;
}
#main{
	width: 700px;
	margin: auto;
	padding: 0 0 100px 50px;
	background-color: #fff;
	text-align: left;
	font-size: 14px;
}
h1{
	margin: 0;
	padding: 60px 0 5px 0;
	font-size: 2em;
}
label{
	display: block;
	float: left;
	width: 50px;
	margin: 2px 4px 0 0;
	text-align: right;
}
p{
	margin: 3px 0 3px 0;
}
.txtGris{
	color: #777;
}
#uploadFileDropArea{
	display: none;
	margin: 10px 150px 10px 50px;
	padding: 30px 0 30px 20px;
	border: 3px dashed #ddd;
	color: #ddd;
	font-weight: bold;
	text-transform: uppercase;
}
#uploadFileDropArea.hover{
	border-color: #80FF00;
	color: #80FF00;
}
	</style>
</head>
<body>

<div id="main">
	<h1>Envoi de fichier en HTML 5 File avec XMLHttpRequest</h1>
	<form id="uploadForm" action="upload.php" method="POST" enctype="multipart/form-data">
		<input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="10485760" />
		<p id="uploadFileSelect"><label for="img">Image : </label><input id="uploadFileButton" name="img" type="file"></p>
		<p id="uploadFileDropArea">Glissez votre image ici</p>
		<p><label>&nbsp;</label><span class="txtGris">Fichier de type JPEG, PNG, GIF</span></p>
		<p><label>&nbsp;</label><span class="txtGris">Poids maximum : 10 Mo</span></p>
		<p id="uploadSend"><label> </label><input type="submit" value="Envoyer"></p>
	</form><!--uploadForm-->
	
	<div id="uploadContent">
		<h1>Image</h1>
		<div id="uploadProgress" class="progressBar"><span id="uploadProgressBar" style="width: 0%"></span></div>
		<p id="uploadResult"></p>
	</div><!--uploadContent-->
	
</div><!--main-->

<script type="text/javascript">
//<![CDATA[

// converti des octets en ko (ou Mo, Go, To) selon le cas le plus approprié
function FileConvertSize(aSize){
	aSize = Math.abs(parseInt(aSize, 10));
	var def = [[1, 'octets'], [1024, 'ko'], [1024*1024, 'Mo'], [1024*1024*1024, 'Go'], [1024*1024*1024*1024, 'To']];
	for(var i=0; i<def.length; i++){
		if(aSize<def[i][0]) return (aSize/def[i-1][0]).toFixed(2)+' '+def[i-1][1];
	}
}

// gère un événement de type dragover ou dragleaver
function FileDrag(evt){
	// stop la diffusion de l'évenements dans le DOM
	evt.stopPropagation();
	// empêche le navigateur d'exécuter son comportement par défaut (ouvrir ou afficher le fichier glissé)
	evt.preventDefault();
	// change la classe du bloc
	dropArea.className = (evt.type=="dragover" ? "hover":"");
}

// un fichier est déposé dans la zone
function FileSelectHandler(evt){
	// appelle la fonction qui gère le drag and drop pour stopper
	FileDrag(evt);
	UploadFile(evt.dataTransfer.files[0]);
}

// envoi un fichier
function UploadFile(file){
	// crée une nouvelle requette XMLHttpRequest
	if(!objRequest.upload){
		// on ne peut pas envoyer de fichier avec XMLHttpRequest
		uploadResult.innerHTML = "Votre naviguateur ne supporte pas l'envoi de fichier";
		
	}else if(file.size > document.getElementById("MAX_FILE_SIZE").value){
		// le fichier est trop gros
		uploadResult.innerHTML = "Le fichier est trop gros. Limite : "+FileConvertSize(document.getElementById("MAX_FILE_SIZE").value);
		
	}else if(!(file.type=="image/jpeg" || file.type=="image/png" || file.type=="image/gif")){
		// le fichier n'est pas du bon type
		uploadResult.innerHTML = "Le type du fichier est incorrect : PNG, JPG, GIF";
		
	}else{
		// tout est ok, on peut envoyer le fichier
		// crée une fonction pour afficher la progresion de la requete
		objRequest.upload.onprogress = function(evt){
			if(evt.lengthComputable){
				var percent = Math.ceil((evt.loaded / evt.total)*100);
				document.getElementById("uploadProgressBar").style.width = percent+'%';
				uploadResult.innerHTML = percent+' %';
			}
		}
		// onreadystatechange est appellé à chaque changement d'état de la requete
		objRequest.onreadystatechange=function(){
			if(objRequest.readyState==4 && objRequest.status==200){
				uploadResult.innerHTML = objRequest.responseText;
			}
		}
		var formData = new FormData();
		formData.append("img", file);
		// ouvre une requete post, avec l'adresse du formulaire
		objRequest.open("POST", document.getElementById("uploadForm").action, true);
		// on envois le fichier
		objRequest.send(formData);
		// indique le début du chargement
		uploadResult.innerHTML = "Chargement en cours";
		// affiche la barre de progression
		document.getElementById("uploadProgress").style.display = "block";
	}
}

// défini quelques variables
var dropArea = document.getElementById("uploadFileDropArea");
var uploadResult =  document.getElementById("uploadResult");
var uploadFileSelect =  document.getElementById("uploadFileSelect");
var objRequest = new XMLHttpRequest();

// ajoute la gestion du glissé déposé si le navigateur est capable de gérer l'envoi de fichier
if(objRequest.upload){
	dropArea.addEventListener("dragover", FileDrag, false);
	dropArea.addEventListener("dragleave", FileDrag, false);
	dropArea.addEventListener("drop", FileSelectHandler, false);
	// affiche la zone sur laquelle l'utilisateur peut glisser un fichier
	dropArea.style.display = "block";
	// masque le bouton de sélection de fichier
	uploadFileSelect.style.display = "none";
	// masque le bouton d'envoi
	document.getElementById("uploadSend").style.display = "none";
	
}else{
	// masque la zone de dépose du fichier
	dropArea.style.display = "none";
}
//]]>
</script>

</body>
</html>