début du téléchargement du fichier avec JavaScript

disons que j'ai des liens de téléchargement pour les fichiers sur mon site.

lorsque vous cliquez sur ces liens, envoyez une requête AJAX au serveur qui renvoie l'URL avec l'emplacement du fichier.

ce que je veux faire est de demander au navigateur de télécharger le fichier lorsque la réponse revient. Y a-t-il un moyen portable de faire ça?

51
demandé sur Baptiste L 2008-12-14 00:37:03

12 réponses

essayez ce lib https://github.com/PixelsCommander/Download-File-JS il est plus moderne que toutes les solutions décrites avant parce que utilise l'attribut" télécharger " et la combinaison de méthodes pour apporter la meilleure expérience possible.

expliquée ici - http://pixelscommander.com/en/javascript/javascript-file-downliading-ignore-content-type/

semble être le morceau de code idéal pour commencer le téléchargement en JavaScript.

3
répondu PixelCommander 2013-10-26 22:11:18

nous le faisons de cette façon: Ajoutez d'abord ce script.

<script type="text/javascript">
function populateIframe(id,path) 
{
    var ifrm = document.getElementById(id);
    ifrm.src = "download.php?path="+path;
}
</script>

placez ceci où vous voulez le bouton de téléchargement (ici, nous utilisons juste un lien):

<iframe id="frame1" style="display:none"></iframe>
<a href="javascript:populateIframe('frame1','<?php echo $path; ?>')">download</a>

le fichier 'download.php' (doit être mis sur votre serveur) contient simplement:

<?php 
   header("Content-Type: application/octet-stream");
   header("Content-Disposition: attachment; filename=".$_GET['path']);
   readfile($_GET['path']);
?>

ainsi, lorsque vous cliquez sur le lien, l'iframe cachée obtient/ouvre le téléchargement du fichier source.php". Avec le chemin comme paramètre get. Nous pensons que c'est la meilleure solution!

il est à noter que la partie PHP de cette solution est une simple démonstration et potentiellement très, très peu sûre. Il permet à l'utilisateur de télécharger n'importe quel fichier, pas seulement un ensemble prédéfini. Cela signifie qu'ils pourraient télécharger des parties du code source du site lui-même, éventuellement contenant des justificatifs D'identité API, etc.

25
répondu roulio 2015-09-21 20:19:24

j'ai créé un open source jQuery Fichier Télécharger plugin ( démo avec des exemples ) ( GitHub ) qui pourrait également aider avec votre situation. Il fonctionne assez similaire avec un iframe, mais a quelques fonctionnalités intéressantes que j'ai trouvé très pratique:

  • L'utilisateur ne quitte jamais la même page à partir de laquelle il a commencé à télécharger un fichier. Cette fonctionnalité devient cruciale pour les applications web modernes
  • testé le soutien de navigateur croisé (y compris mobile!)
  • il supporte les requêtes POST et GET d'une manière similaire à L'API AJAX de jQuery
  • les fonctions successCallback et failCallback vous permettent d'être explicite sur ce que l'utilisateur voit dans l'une ou l'autre des situations
  • en conjonction avec jQuery UI un développeur peut facilement montrer un modal disant à l'utilisateur qu'un téléchargement de fichier est en cours, téléchargement démarre ou même informer l'utilisateur d'une manière amicale qu'une erreur s'est produite. Voir la Démo pour un exemple de cette.
18
répondu John Culviner 2012-06-21 21:53:05

lire les réponses - y compris celle acceptée j'aimerais souligner les implications de sécurité de passer un chemin directement à readfile via GET.

cela peut sembler évident à certains mais certains peuvent simplement copier / coller ce code:

<?php 
   header("Content-Type: application/octet-stream");
   header("Content-Disposition: attachment; filename=".$_GET['path']);
   readfile($_GET['path']);
?>

alors que se passe-t-il si je passe quelque chose comme '/path/to/fileWithSecrets' à ce script? Le script donné enverra volontiers n'importe quel fichier auquel le serveur web-Utilisateur a accès.

S'il vous plaît Comment éviter cela: comment m'assurer qu'un chemin de fichier se trouve dans un sous-répertoire donné?

14
répondu DanielKhan 2017-05-23 11:46:48

si c'est votre propre application serveur, je vous suggère d'utiliser l'en-tête suivant

Content-disposition: attachment; filename=fname.ext

ceci forcera n'importe quel navigateur à télécharger le fichier et à ne pas le rendre dans la fenêtre du navigateur.

10
répondu fasih.rana 2008-12-13 23:10:54

il suffit d'appeler window.location.href = new_url à partir de votre javascript et il redirigera le navigateur à cette URL comme il l'Utilisateur a tapé que dans la barre d'adresse

7
répondu Gareth 2008-12-13 23:20:13

a d'accord avec les méthodes mentionnées par maxnk, cependant vous pouvez vouloir reconsidérer essayer de forcer automatiquement le navigateur à télécharger l'URL. Il peut fonctionner très bien pour les fichiers binaires, mais pour d'autres types de fichiers (texte, PDF, images, vidéo), le navigateur peut vouloir le rendre dans la fenêtre (ou IFRAME) plutôt que d'enregistrer sur le disque.

si vous avez vraiment besoin de faire un appel Ajax pour obtenir les liens de téléchargement final, que diriez-vous D'utiliser DHTML pour écrire dynamiquement télécharger le lien (de la réponse ajax) dans la page? De cette façon, l'utilisateur peut soit cliquer dessus pour télécharger (si binaire) ou afficher dans son navigateur - ou sélectionner "Enregistrer sous" sur le lien pour enregistrer sur le disque. C'est un clic supplémentaire, mais l'Utilisateur a plus de contrôle.

3
répondu Marc Novakowski 2008-12-13 22:14:33

Pour contourner la faille de sécurité dans le haut-voté réponse, vous pouvez définir l'iframe src directement le fichier que vous voulez (au lieu d'un intermédiaire fichier php) et définir les informations d'en-tête dans un .fichier htaccess:

<Files *.apk>
     ForceType application/force-download
     Header set Content-Disposition attachment
     Header set Content-Type application/vnd.android.package-archive
     Header set Content-Transfer-Encoding binary
</Files>
3
répondu Matt K 2014-03-14 18:26:37

je suggère de faire une iframe invisible sur la page et de la mettre en src à l'url que vous avez reçu du serveur - le téléchargement va commencer sans page recharger.

ou vous pouvez simplement définir le document courant.emplacement.href à l'adresse url reçue. Mais cela peut amener l'utilisateur à voir une erreur si le document demandé n'existe pas.

2
répondu maxnk 2008-12-13 22:07:48

en ce qui concerne la réponse supérieure, j'ai une solution possible au risque de sécurité.

<?php
     if(isset($_GET['path'])){
         if(in_array($_GET['path'], glob("*/*.*"))){
             header("Content-Type: application/octet-stream");
             header("Content-Disposition: attachment; filename=".$_GET['path']);
             readfile($_GET['path']);
         }
     }
?>

en utilisant la fonction glob () (j'ai testé le fichier de téléchargement dans un chemin un dossier vers le haut à partir du fichier à télécharger) j'ai été en mesure de faire un tableau rapide de fichiers qui sont" autorisés " à être téléchargés et vérifié le chemin passé contre elle. Non seulement cela assure que le fichier saisi n'est pas quelque chose de sensible, mais vérifie également l'existence des fichiers au même temps.

~Note: Javascript / HTML~

HTML:

<iframe id="download" style="display:none"></iframe>

et

<input type="submit" value="Download" onclick="ChangeSource('document_path');return false;">

JavaScript:

<script type="text/javascript">
    <!--
        function ChangeSource(path){
            document.getElementByID('download').src = 'path_to_php?path=' + document_path;
        }
    -->
</script>
2
répondu James Bordine II 2015-09-17 18:14:52

je suggère window.open() pour ouvrir une fenêtre contextuelle. Si c'est un téléchargement, il n'y aura pas de fenêtre et vous obtiendrez votre fichier. S'il y a un 404 ou quelque chose, l'utilisateur le verra dans une nouvelle fenêtre (par conséquent, leur travail ne sera pas dérangé, mais ils obtiendront quand même un message d'erreur).

1
répondu Vilx- 2008-12-13 22:24:29

Pourquoi faites-vous des trucs côté serveur quand tout ce dont vous avez besoin est de rediriger le navigateur vers une fenêtre différente.emplacement.href?

voici le code qui passe ?fichier= QueryString ( tiré de cette question ) et redirige l'utilisateur à cette adresse en 1 seconde (fonctionne pour moi même sur les navigateurs Android):

<script type="text/javascript">
    var urlParams;
    (window.onpopstate = function () {
        var match,
        pl = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
        query = window.location.search.substring(1);

        urlParams = {};
        while (match = search.exec(query))
            urlParams[decode(match[1])] = decode(match[2]);
    })();

    (window.onload = function() {
        var path = urlParams["file"];
        setTimeout(function() { document.location.href = path; }, 1000);
    });
</script>

si vous avez jQuery dans votre projet certainement supprimer cette fenêtre.onpopstate & window.gestionnaires de charges et do tout en $(document).ready (function () {});

1
répondu kape123 2017-05-23 11:54:12