Pourquoi est-ce qu'il n'y a aucun moyen de télécharger un fichier en utilisant la requête ajax?

Dans notre application, nous devons mettre en œuvre le scénario suivant:

  1. Une demande est envoyée par le client
  2. Le serveur gère la demande et génère un fichier
  3. Le serveur retourne le fichier en réponse
  4. Le navigateur client affiche une boîte de dialogue contextuelle de téléchargement de fichier et permet à l'utilisateur de télécharger le fichier

Notre application est une application basée ajax, donc il serait très facile et pratique pour nous d'envoyer une requête ajax (comme l'utilisation de la fonction jquery.ajax() ).

Mais après googilng, il s'est avéré que le téléchargement de fichiers n'est possible que lorsque vous utilisez une demande POST non-ajax (comme décrit dans ce thread SO populaire ). Nous devions donc implémenter une solution plus complexe et plus complexe qui exigeait la construction d'une structure HTML de form avec des champs cachés imbriqués.

Quelqu'un pourrait-il expliquer en mots simples pourquoi les requêtes ajax ne peuvent-elles pas être utilisées pour télécharger un fichier? Quelle est la mécanique derrière cela?

Il ne s'agit pas d'AJAX. Vous pouvez télécharger un fichier avec AJAX, bien sûr. Cependant, le fichier sera conservé en mémoire, c'est-à-dire que vous ne pouvez pas enregistrer le fichier sur le disque. C'est parce que JavaScript ne peut pas interagir avec le disque. Ce serait un grave problème de sécurité et il est bloqué dans tous les principaux navigateurs.

Cela peut être fait en utilisant la nouvelle fonction HTML5 appelée Blob. Il existe une bibliothèque FileSaver.js qui peut être utilisée comme un wrapper au-dessus de cette fonctionnalité.

C'est la même question que je me suis posée il y a deux jours. Il y avait un projet avec client écrit en utilisant ExtJS et la réalisation du côté serveur était sur ASP.Net. Je dois traduire côté serveur vers Java. Il y avait une fonction pour télécharger un fichier XML, ce serveur génère après la demande Ajax du client. Nous savons tous qu'il est impossible de télécharger le fichier après la demande d'Ajax, juste pour le mémoriser. Mais … dans le navigateur de l'application d'origine apparaît la boîte de dialogue habituelle avec les options ouvertes, sauvegarder et annuler le téléchargement. ASP.Net a en quelque sorte changé le comportement standard … Il me faut deux jours pour prouver à nouveau – il n'y a aucun moyen de télécharger le fichier par la manière habituelle … la seule exception est ASP.Net … Voici ASP.Net code

 public static void WriteFileToResponse(byte[] fileData, string fileName) { var response = HttpContext.Current.Response; var returnFilename = Path.GetFileName(fileName); var headerValue = String.Format("attachment; filename={0}", HttpUtility.UrlPathEncode( String.IsNullOrEmpty(returnFilename) ? "attachment" : returnFilename)); response.AddHeader("content-disposition", headerValue); response.ContentType = "application/octet-stream"; response.AddHeader("Pragma", "public"); var utf8 = Encoding.UTF8; response.Charset = utf8.HeaderName; response.ContentEncoding = utf8; response.Flush(); response.BinaryWrite(fileData); response.Flush(); response.Close(); } 

Cette méthode a été appelée à partir de WebMethod, qui, à son tour, a été appelée depuis ExtJS.Ajax.request. C'est la magie. Qu'en est-il, j'ai fini avec le servlet et l'iframe caché …

Vous pouvez le faire en utilisant un iframe caché dans votre page de téléchargement

Il suffit de définir la src de l'ifame caché dans votre réponse de succès ajax et votre tâche est terminée …

  $.ajax({ type: 'GET', url: './page.php', data: $("#myform").serialize(), success: function (data) { $("#middle").attr('src','url'); }, });