J'ai une action Struts2 côté serveur pour le téléchargement de fichiers.
<action name="download" class="com.xxx.DownAction">
<result name="success" type="stream">
<param name="contentType">text/plain</param>
<param name="inputName">imageStream</param>
<param name="contentDisposition">attachment;filename={fileName}</param>
<param name="bufferSize">1024</param>
</result>
</action>
Cependant, lorsque j'appelle l'action à l'aide de jQuery:
$.post(
"/download.action",{
para1:value1,
para2:value2
....
},function(data){
console.info(data);
}
);
dans Firebug, je vois que les données sont récupérées avec le flux binaire . Je me demande comment ouvrir le fenêtre de téléchargement de fichier avec laquelle l'utilisateur peut enregistrer le fichier localement?
Réponses:
Mise à jour des navigateurs modernes 2019
C'est l'approche que je recommanderais maintenant avec quelques mises en garde:
2012 Approche originale basée sur jQuery / iframe / Cookie
Bluish a tout à fait raison, vous ne pouvez pas le faire via Ajax car JavaScript ne peut pas enregistrer les fichiers directement sur l'ordinateur d'un utilisateur (par souci de sécurité). Malheureusement, pointer l' URL de la fenêtre principale vers le téléchargement de votre fichier signifie que vous avez peu de contrôle sur l'expérience utilisateur lorsqu'un téléchargement de fichier se produit.
J'ai créé jQuery File Download qui permet une expérience "Ajax like" avec des téléchargements de fichiers complets avec les rappels OnSuccess et OnFailure pour offrir une meilleure expérience utilisateur. Jetez un œil à mon article de blog sur le problème commun que le plugin résout et sur certaines façons de l'utiliser, ainsi qu'une démonstration de jQuery File Download en action . Voici la source
Voici une démo de cas d'utilisation simple utilisant la source du plugin avec des promesses. La page de démonstration comprend également de nombreux autres exemples de «meilleure expérience utilisateur».
Selon les navigateurs dont vous avez besoin pour prendre en charge, vous pourrez peut-être utiliser https://github.com/eligrey/FileSaver.js/ qui permet un contrôle plus explicite que la méthode IFRAME que jQuery File Download utilise.
la source
Personne n'a posté cette solution @ Pekka ... alors je vais la poster. Cela peut aider quelqu'un.
Vous n'avez pas besoin de le faire via Ajax. Utilisez simplement
la source
window.open(<url>, '_blank');
pour vous assurer que le téléchargement ne remplacera pas le contenu de votre navigateur actuel (quel que soit l'en-tête Content-Disposition).POST
demande.Vous pouvez avec HTML5
NB: Les données de fichier renvoyées DOIVENT être codées en base64 car vous ne pouvez pas coder en JSON des données binaires
Dans ma
AJAX
réponse, j'ai une structure de données qui ressemble à ceci:Cela signifie que je peux faire ce qui suit pour enregistrer un fichier via AJAX
La fonction base64ToBlob a été prise à partir d' ici et doit être utilisée conformément à cette fonction
C'est bien si votre serveur vide les fichiers à enregistrer. Cependant, je n'ai pas tout à fait compris comment on implémenterait une solution de secours HTML4
la source
a.click()
ne semble pas fonctionner sous firefox ... Une idée?a
au dom pour que ce code fonctionne et / ou supprimer larevokeObjectURL
partie:document.body.appendChild(a)
var bytechars = atob(base64)
il lance une erreurJavaScript runtime error: InvalidCharacterError
. J'utilise la version 75.0.3770.142 de Chrome, mais je ne sais pas ce qui ne va pas ici.1. Framework agnostique: fichier de téléchargement de servlet en pièce jointe
2. Struts2 Framework: fichier de téléchargement d'actions en pièce jointe
Il serait préférable d'utiliser une
<s:a>
balise pointant avec OGNL vers une URL créée avec une<s:url>
balise:Dans les cas ci-dessus, vous devez écrire l'en - tête Content-Disposition dans la réponse , en spécifiant que le fichier doit être téléchargé (
attachment
) et non ouvert par le navigateur (inline
). Vous devez spécifier le type de contenu et vous pouvez ajouter le nom et la longueur du fichier (pour aider le navigateur à dessiner une barre de progression réaliste).Par exemple, lors du téléchargement d'un ZIP:
Avec Struts2 (sauf si vous utilisez l'action en tant que servlet, un hack pour le streaming direct , par exemple), vous n'avez pas besoin d'écrire directement quoi que ce soit dans la réponse; simplement utiliser le type de résultat Stream et le configurer dans struts.xml fonctionnera: EXEMPLE
3. Framework agnostique (framework / Struts2): fichier d'ouverture Servlet (/ Action) dans le navigateur
Si vous souhaitez ouvrir le fichier à l'intérieur du navigateur, au lieu de le télécharger, la disposition de contenu doit être définie sur inline , mais la cible ne peut pas être l'emplacement actuel de la fenêtre; vous devez cibler une nouvelle fenêtre créée par javascript, un
<iframe>
dans la page, ou une nouvelle fenêtre créée à la volée avec la cible "discutée" = "_ vide":la source
too long url
erreur.Le moyen simple pour que le navigateur télécharge un fichier est de faire la demande comme ça:
Cela ouvre la fenêtre de téléchargement du navigateur.
la source
J'ai créé une petite fonction comme solution de contournement (inspirée du plugin @JohnCulviner):
Démo avec événement click:
la source
J'ai fait face au même problème et l'ai résolu avec succès. Mon cas d'utilisation est le suivant.
" Publiez des données JSON sur le serveur et recevez un fichier Excel. Ce fichier Excel est créé par le serveur et renvoyé comme réponse au client. Téléchargez cette réponse sous forme de fichier avec un nom personnalisé dans le navigateur "
L'extrait ci-dessus ne fait que suivre
Ici, nous devons soigneusement définir quelques éléments côté serveur. J'ai défini quelques en-têtes dans Python Django HttpResponse. Vous devez les définir en conséquence si vous utilisez d'autres langages de programmation.
Depuis que je télécharge xls (excel) ici, j'ai ajusté contentType au dessus. Vous devez le définir en fonction de votre type de fichier. Vous pouvez utiliser cette technique pour télécharger tout type de fichiers.
la source
HTMLAnchorElement.download
, je pense à le combiner avec la méthode propriétaire msSaveOrOpenBlob .Ok, basé sur le code de ndpu, voici une version améliorée (je pense) de ajax_download; -
Utilisez ceci comme ceci; -
Les paramètres sont envoyés comme des paramètres de publication appropriés, comme s'ils provenaient d'une entrée plutôt que comme une chaîne codée json, comme dans l'exemple précédent.
CAVEAT: Méfiez-vous du potentiel d'injection variable sur ces formes. Il pourrait y avoir un moyen plus sûr d'encoder ces variables. Vous pouvez également envisager de leur échapper.
la source
Uncaught SecurityError: Blocked a frame with origin "http://foo.bar.com" from accessing a frame with origin "null". The frame requesting access has a protocol of "http", the frame being accessed has a protocol of "data". Protocols must match.
@ResourceMapping() public void downloadFile(final ResourceRequest request, final ResourceResponse response, @ModelAttribute("downForm") FormModel model)
mais ça ne marche pas ..Voici ce que j'ai fait, pur javascript et html. Je ne l'ai pas testé mais cela devrait fonctionner dans tous les navigateurs.
la source
la source
download
attribut, donc votre fichier finira par avoir le nom "Inconnu"Dans Rails, je le fais de cette façon:
L'astuce est la partie window.location . La méthode du contrôleur ressemble à ceci:
la source
Utilisation
window.open
https://developer.mozilla.org/en-US/docs/Web/API/Window/openPar exemple, vous pouvez placer cette ligne de code dans un gestionnaire de clics:
Il ouvrira un nouvel onglet (en raison du nom de fenêtre '_blank') et cet onglet ouvrira l'URL.
Votre code côté serveur devrait également avoir quelque chose comme ceci:
Et de cette façon, le navigateur devrait inviter l'utilisateur à enregistrer le fichier sur le disque, au lieu de simplement lui montrer le fichier. Il fermera également automatiquement l'onglet qu'il vient d'ouvrir.
la source
J'essaie de télécharger un fichier CSV, puis je fais quelque chose une fois le téléchargement terminé. J'ai donc besoin de mettre en œuvre un
callback
fonction .En utilisant
window.location="..."
n'est pas une bonne idée car je ne peux pas utiliser le programme après avoir terminé le téléchargement. Quelque chose comme ça, changez d'en-tête donc ce n'est pas une bonne idée.fetch
est une bonne alternative mais ne peut pas prendre en charge IE 11 . Etwindow.URL.createObjectURL
ne peut pas prendre en charge IE 11. Vous pouvez vous référer à ce .Ceci est mon code, il est similaire au code de Shahrukh Alam. Mais vous devez faire attention à ce que cela
window.URL.createObjectURL
crée des fuites de mémoire. Vous pouvez vous référer à cela . Lorsque la réponse est arrivée, les données seront stockées dans la mémoire du navigateur. Donc, avant de cliquer sur lea
lien, le fichier a été téléchargé. Cela signifie que vous pouvez faire n'importe quoi après le téléchargement.la source
Comment TÉLÉCHARGER un fichier après l'avoir reçu par AJAX
C'est pratique lorsque le fichier est créé depuis longtemps et que vous devez montrer PRELOADER
Exemple lors de la soumission d'un formulaire Web:
La fonctionnalité optionnelle est commentée pour simplifier l'exemple.
Pas besoin de créer des fichiers temporaires sur le serveur.
Sur jQuery v2.2.4 OK. Il y aura une erreur sur l'ancienne version:
la source
filename.match(/filename=(.*)/)[1]
(sans les guillemets doubles ou le point d'interrogation) - regex101.com/r/2AsD4y/2 . Cependant, votre solution était la seule solution qui a fonctionné après beaucoup de recherches.Ajouter d'autres éléments à la réponse ci-dessus pour télécharger un fichier
Ci-dessous est un code java spring qui génère un tableau d'octets
Maintenant, en code javascript en utilisant FileSaver.js, vous pouvez télécharger un fichier avec le code ci-dessous
Ce qui précède téléchargera le fichier
la source
Ok, voici donc le code de travail lors de l'utilisation de MVC et vous obtenez votre fichier à partir d'un contrôleur
disons que votre tableau d'octets déclare et remplit, la seule chose que vous devez faire est d'utiliser la fonction File (en utilisant System.Web.Mvc)
puis, dans le même contrôleur, ajoutez ces 2 fonctions
puis vous pourrez appeler votre contrôleur pour télécharger et obtenir le rappel "succès" ou "échec"
la source
J'ai trouvé un correctif qui, bien qu'il n'utilise pas réellement ajax, vous permet d'utiliser un appel javascript pour demander le téléchargement, puis d'obtenir un rappel lorsque le téléchargement démarre réellement. J'ai trouvé cela utile si le lien exécute un script côté serveur qui prend un peu pour composer le fichier avant de l'envoyer. afin que vous puissiez les alerter en cours de traitement, puis quand il envoie enfin le fichier, supprimez cette notification de traitement. c'est pourquoi je voulais essayer de charger le fichier via ajax pour commencer afin que je puisse avoir un événement quand le fichier est demandé et un autre quand il commence réellement à télécharger.
les js en première page
l'iframe
puis l'autre fichier:
Je pense qu'il y a un moyen de lire obtenir des données en utilisant js, alors aucun php ne serait nécessaire. mais je ne le sais pas et le serveur que j'utilise supporte le php donc cela fonctionne pour moi. pensais que je le partagerais au cas où cela aiderait quelqu'un.
la source
Si vous souhaitez utiliser jQuery File Download, veuillez le noter pour IE. Vous devez réinitialiser la réponse ou elle ne sera pas téléchargée
Votre action peut mettre
ServletResponseAware
en œuvre pour accédergetServletResponse()
la source
Il est certain que vous ne pouvez pas le faire via un appel Ajax.
Cependant, il existe une solution de contournement.
Pas :
Si vous utilisez form.submit () pour télécharger le fichier, ce que vous pouvez faire est:
Ceci est utile dans le cas où vous souhaitez décider si le fichier doit être téléchargé ou non après avoir créé form.submit (), par exemple: il peut y avoir un cas où sur form.submit (), une exception se produit côté serveur et à la place de planter, vous devrez peut-être afficher un message personnalisé du côté client, dans ce cas, cette implémentation pourrait vous aider.
la source
il existe une autre solution pour télécharger une page web en ajax. Mais je fais référence à une page qui doit d'abord être traitée puis téléchargée.
Vous devez d'abord séparer le traitement de la page du téléchargement des résultats.
1) Seuls les calculs de page sont effectués dans l'appel ajax.
J'espère que cette solution pourra être utile à beaucoup, comme elle l'a été pour moi.
la source
la source
Ça marche si bien dans n'importe quel navigateur (j'utilise le noyau asp.net)
la source
J'ai lutté avec ce problème pendant longtemps. Enfin, une élégante bibliothèque externe suggérée ici m'a aidé.
la source