Ajax et Upload - part 1
Si vous faites un peu de JavaScript l'Ajax, vous savez certainement que l'on ne peut pas envoyer un fichier : un <input type="file" /> via une requête XMLHttpRequest. Je vous avez déjà parlé d'une solution ici : upload avec Ajax. Mais intéressons nous d'un peu plus prêt au fonctionnement.
Tout d'abord comment fonctionne un upload normal, en HTML, sans Ajax ni quoi que ce soit ?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
</head>
<body>
<form action="Default4.aspx" enctype="multipart/form-data" method="post">
<input type="file" id="file1" name="file1" />
<input type="submit" id="btn1" value="Envoyer" />
</form>
</body>
</html>
L'attribut enctype est nécessaire pour envoyer des fichiers binaires en HTTP, ceci est spécifié dans la RFC 2388.
Ce que l'on veut maintenant c'est envoyer le fichier sans recharger toute la page. L'attribut target de la balise form permet d'envoyer le formulaire dans une autre frame/iframe, on va donc envoyer notre formulaire dans une iframe.
<body>
<form action="Default4.aspx" enctype="multipart/form-data" method="post" target="hiddeniframe">
<input type="file" id="file1" name="file1" />
<input type="submit" id="btn1" value="Envoyer" />
</form>
<iframe name="hiddeniframe" src="about:blank"></iframe>
</body>
Maintenant, lorsque l'on clique sur le bouton "envoyer", toute la page ne se rafraichit pas, seulement l'iframe. On aimerait bien avoir un message à coté du bouton qui indique que le fichier a bien été envoyé. Pour cela notre iframe doit communiquer avec sa page parente.
Tout d'abord rajoutons un peu de JavaScript dans la page parente :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
<script type="text/javascript">
var CS = {};
CS.UploadAjax = function(){}
CS.UploadAjax.callBack = function(message){
document.getElementById('messageCallBack').innerHTML = message;
}
</script>
</head>
<body>
<form action="Default4.aspx" enctype="multipart/form-data" method="post" target="hiddeniframe">
<input type="file" id="file1" name="file1" />
<input type="submit" id="btn1" value="Envoyer" />
<div id="messageCallBack"></div>
</form>
<iframe name="hiddeniframe" style="display:none;" src="about:blank"></iframe>
</body>
</html>
Dans la page Default4.aspx il suffit alors de renvoyer :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
<script type="text/javascript">
window.parent.CS.UploadAjax.callBack('fichier envoyé avec succès 55430 octets')
</script>
</head>
<body>
</body>
</html>
A partir de maintenant lorsque l'on clique sur le bouton envoyer, un message apparait en indiquant la taille du fichier et cela sans recharger la page.
On pourrais aller plus loin, en générant automatiquement l'iframe lorsque l'on clique sur le bouton, il existe de nombreux exemples sur le net le faisant, par exemple celui-ci : Ajax file upload.
Dans une prochaine partie, nous verrons comment utiliser cette astuce pour activer le contrôle fileUpload dans un UpdatePanel.
[Edit] : La partie 2 est disponible ici : Ajax et Upload - part 2 : Utilisation d'un UpdatePanel et d'un FileUpload