web-dev-qa-db-fra.com

Envoyer un fichier en plusieurs parties via xmlHttpRequest

Puis-je envoyer un fichier en plusieurs parties par XMLHttpRequest à un servlet? Je crée un formulaire et je le soumets en plusieurs parties, mais je ne reçois pas de réponse pour le télécharger avec succès. Je ne veux pas que la page soit rafraîchie, elle doit donc être effectuée par ajax.

24
Tejasva Dhyani

Cela n'est possible qu'avec XHR FormData API (auparavant connu comme faisant partie de "XHR2" ou "XHR Level 2", actuellement connu sous le nom de "XHR Advanced Features").

Compte tenu de ce HTML,

<input type="file" id="myFileField" name="myFile" />

vous pouvez le télécharger comme ci-dessous:

var formData = new FormData();
formData.append("myFile", document.getElementById("myFileField").files[0]);

var xhr = new XMLHttpRequest();
xhr.open("POST", "myServletUrl");
xhr.send(formData);

XHR prendra soin des en-têtes appropriés et demandera l'encodage du corps. Dans cet exemple, le fichier sera disponible côté serveur en tant que partie form-data Avec le nom myFile.

Vous devez garder à l'esprit que l'API FormData n'est pas prise en charge dans les anciens navigateurs. Sur caniuse.com vous pouvez voir qu'il est actuellement implémenté dans Chrome 7+, Firefox 3.5+, Safari 5+, IE 10+ et Opera 12+.

Une alternative est d'utiliser le plugin jQuery Form . Votre formulaire entier, lorsqu'il est écrit et fonctionne correctement sans aucune ligne de code JavaScript, sera ensuite instantanément ajaxifié avec juste la ligne suivante:

$("#formId").ajaxForm(function(response) {
    // Handle ajax response here.
});

Il prend également en charge le téléchargement de fichiers par une astuce iframe cachée. Voir aussi cette documentation du formulaire jQuery pour une explication détaillée. Vous n'aurez peut-être qu'à modifier le code de servlet pour pouvoir intercepter à la fois les demandes normales (synchrones) et ajax (asynchrones). Voir aussi cette réponse pour un exemple concret: Calculatrice simple avec JSP/Servlet et Ajax

Dans tous les cas, le fichier téléchargé devrait alors être disponible dans la méthode doPost() d'une servlet @MultipartConfig comme suit:

Part myFile = request.getPart("myFile");

Ou si vous utilisez toujours Servlet 2.5 ou une version antérieure, utilisez Apache Commons FileUpload de la manière habituelle. Voir aussi cette réponse pour un exemple concret: Comment télécharger des fichiers sur le serveur en utilisant JSP/Servlet?

58
BalusC

Il n'est pas possible d'envoyer multipart/form-data avec xhr (pdate: bien que cela soit possible dans les navigateurs modernes, avec XHR2. Voir la réponse de BalusC).

Une manière courante de réaliser ce que vous voulez est d'utiliser un form régulier, mais dans un iframe à la place. De cette façon, seul le iframe est actualisé lors du téléchargement.