J'ai une application web à une seule page basée sur Jquery. Elle communique avec un service web RESTful via des appels AJAX.
J'essaie d'accomplir ce qui suit :
- Soumettre un POST qui contient des données JSON à une url REST.
- Si la demande spécifie une réponse JSON, alors JSON est retourné.
- Si la demande spécifie une réponse PDF/XLS/etc, alors un binaire téléchargeable est renvoyé.
J'ai 1 et 2 qui fonctionnent maintenant, et l'application jquery du client affiche les données retournées dans la page web en créant des éléments DOM basés sur les données JSON. Le point 3 fonctionne également du point de vue du service web, ce qui signifie qu'il créera et renverra un fichier binaire si les paramètres JSON sont corrects. Mais je ne suis pas sûr de la meilleure façon de traiter le point 3 dans le code javascript du client.
Est-il possible de récupérer un fichier téléchargeable à partir d'un appel ajax comme celui-ci ? Comment faire pour que le navigateur télécharge et enregistre le fichier ?
$.ajax({
type: "POST",
url: "/services/test",
contentType: "application/json",
data: JSON.stringify({category: 42, sort: 3, type: "pdf"}),
dataType: "json",
success: function(json, status){
if (status != "success") {
log("Error loading data");
return;
}
log("Data loaded!");
},
error: function(result, status, err) {
log("Error loading data");
return;
}
});
Le serveur répond avec les en-têtes suivants :
Content-Disposition:attachment; filename=export-1282022272283.pdf
Content-Length:5120
Content-Type:application/pdf
Server:Jetty(6.1.11)
Une autre idée consiste à générer le PDF, à le stocker sur le serveur et à renvoyer un JSON comprenant une URL vers le fichier. Ensuite, émettez un autre appel dans le gestionnaire de succès ajax pour faire quelque chose comme ce qui suit :
success: function(json,status) {
window.location.href = json.url;
}
Mais cela signifie que je devrais faire plus d'un appel au serveur, et que mon serveur devrait créer des fichiers téléchargeables, les stocker quelque part, puis nettoyer périodiquement cette zone de stockage.
Il doit y avoir un moyen plus simple d'y parvenir. Des idées ?
EDIT : Après avoir examiné la documentation relative à $.ajax, je constate que le type de données de la réponse ne peut être qu'un des éléments suivants xml, html, script, json, jsonp, text
Je suppose donc qu'il n'y a aucun moyen de télécharger directement un fichier à l'aide d'une requête ajax, à moins que je n'intègre le fichier binaire en utilisant le schéma URI des données comme le suggère la réponse de @VinayC (ce que je ne souhaite pas faire).
Donc je suppose que mes options sont :
-
Ne pas utiliser l'ajax, mais plutôt soumettre un formulaire et intégrer mes données JSON dans les valeurs du formulaire. Il faudrait probablement s'amuser avec des iframes cachées et autres.
-
Ne pas utiliser ajax et convertir mes données JSON en une chaîne de requête pour construire une requête GET standard et définir window.location.href à cette URL. Vous devrez peut-être utiliser event.preventDefault() dans mon gestionnaire de clics pour empêcher le navigateur de changer l'URL de l'application.
-
Utilisez mon autre idée ci-dessus, mais enrichie des suggestions de la réponse de @naikus. Soumettre une requête AJAX avec un paramètre qui permet au service web de savoir qu'il est appelé via un appel AJAX. Si le service web est appelé à partir d'un appel ajax, renvoyer simplement JSON avec une URL vers la ressource générée. Si la ressource est appelée directement, il faut renvoyer le fichier binaire réel.
Plus j'y pense, plus j'aime la dernière option. De cette façon, je peux obtenir des informations en retour sur la demande (temps de génération, taille du fichier, messages d'erreur, etc.) et je peux agir sur ces informations avant de lancer le téléchargement. L'inconvénient est une gestion supplémentaire des fichiers sur le serveur.
Y a-t-il d'autres moyens d'y parvenir ? Y a-t-il des avantages ou des inconvénients à ces méthodes dont je devrais être conscient ?
0 votes
Duplicata possible de Gérer le téléchargement de fichiers à partir d'un post ajax
7 votes
Celui-ci était "un peu" plus tôt, alors en quoi est-ce un doublon ?
1 votes
url = 'http://localhost/file.php?file='+ $('input').val(); window.open(url);
Le moyen le plus simple d'obtenir les mêmes résultats. Mettez l'en-tête dans le fichier php. Pas besoin d'envoyer des requêtes ajax ou get.