Téléchargez plusieurs fichiers en une seule action

109

Je ne suis pas sûr que cela soit possible en utilisant les technologies Web standard.

Je souhaite que l'utilisateur puisse télécharger plusieurs fichiers en une seule action. C'est-à-dire cliquez sur les cases à cocher en regard des fichiers, puis récupérez tous les fichiers qui ont été vérifiés.

Est-ce possible - si oui, quelle stratégie de base recommandez-vous. Je sais que je peux utiliser la technologie des comètes pour créer des événements côté serveur qui déclenchent une HttpResponse, mais j'espère qu'il existe un moyen plus simple.

Ankur
la source

Réponses:

60

HTTP ne prend pas en charge plus d'un téléchargement de fichiers à la fois.

Il existe deux solutions:

  • Ouvrez x quantité de fenêtres pour lancer les téléchargements de fichiers (cela serait fait avec JavaScript)
  • solution préférée créer un script pour compresser les fichiers
Jacob Relkin
la source
39
Pourquoi un fichier zip est-il la solution préférée ? Cela crée une étape supplémentaire pour l'utilisateur (décompression).
speedplane
7
Cette page contient du javascript qui crée un fichier ZIP. Regardez la page, il a un excellent exemple. stuk.github.io/jszip
Netsi1964
Une troisième méthode consiste à encapsuler les fichiers dans un fichier SVG. Si les fichiers sont affichés dans le navigateur, le SVG semble être le meilleur moyen.
VectorVortec
4
HTTP lui-même prend en charge le format de message en plusieurs parties. Mais les navigateurs n'analysent pas de manière portable les réponses en plusieurs parties du côté serveur, mais techniquement, il n'y a rien de difficile à faire.
CMCDragonkai
2
Cela peut être une excellente solution avec javascript github.com/sindresorhus/multi-download
juananruiz
84

var links = [
  'https://s3.amazonaws.com/Minecraft.Download/launcher/Minecraft.exe',
  'https://s3.amazonaws.com/Minecraft.Download/launcher/Minecraft.dmg',
  'https://s3.amazonaws.com/Minecraft.Download/launcher/Minecraft.jar'
];

function downloadAll(urls) {
  var link = document.createElement('a');

  link.setAttribute('download', null);
  link.style.display = 'none';

  document.body.appendChild(link);

  for (var i = 0; i < urls.length; i++) {
    link.setAttribute('href', urls[i]);
    link.click();
  }

  document.body.removeChild(link);
}
<button onclick="downloadAll(window.links)">Test me!</button>

Matěj Pokorný
la source
3
Je travaille avec de nombreux types de fichiers, y compris des images, et cela a fonctionné mieux pour moi. Cependant, link.setAttribute('download', null);j'ai renommé tous mes fichiers en null.
tehlivi
7
Cela ne fonctionne pas dans IE 11, il ne télécharge que le .jar (dernier élément de la liste) c'était la solution parfaite :(
Immutable Brick
1
@AngeloMoreira Oui, au moins ça marche dans Edge. Si vous essayez de télécharger plusieurs fichiers dans IE sur des sites MS, par exemple , ils engendrent plusieurs fenêtres pop-up, donc je pense que la meilleure solution pour IE est toujours de Dmitry Nogin ci-dessus .
Matěj Pokorný
1
@tehlivi - J'ai trouvé la même chose. Ajoutez l' link.setAttribute('download',filename)intérieur de la boucle. Cela vous permet de nommer les fichiers comme vous le souhaitez. De plus, je pense qu'il doit s'agir du nom de fichier uniquement sans inclure l'URL. J'ai fini par envoyer deux tableaux: un avec l'URL complète et un avec juste le nom de fichier.
PhilMDev
7
Cela ne fonctionne pas correctement dans Chrome v75, Windows 10: le seul fichier téléchargé est Minecraft.jar.
andreivictor
54

Vous pouvez créer un ensemble temporaire d'iframes cachés, lancer le téléchargement par GET ou POST à ​​l'intérieur d'eux, attendre que les téléchargements commencent et supprimer les iframes:

<!DOCTYPE HTML>
<html>
<body>
  <button id="download">Download</button> 

  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
  <script type="text/javascript">

     $('#download').click(function() {
       download('http://nogin.info/cv.doc','http://nogin.info/cv.doc');
     });

     var download = function() {
       for(var i=0; i<arguments.length; i++) {
         var iframe = $('<iframe style="visibility: collapse;"></iframe>');
         $('body').append(iframe);
         var content = iframe[0].contentDocument;
         var form = '<form action="' + arguments[i] + '" method="GET"></form>';
         content.write(form);
         $('form', content).submit();
         setTimeout((function(iframe) {
           return function() { 
             iframe.remove(); 
           }
         })(iframe), 2000);
       }
     }      

  </script>
</body>
</html>

Ou, sans jQuery:

 function download(...urls) {
    urls.forEach(url => {
      let iframe = document.createElement('iframe');
      iframe.style.visibility = 'collapse';
      document.body.append(iframe);

      iframe.contentDocument.write(
        `<form action="${url.replace(/\"/g, '"')}" method="GET"></form>`
      );
      iframe.contentDocument.forms[0].submit();

      setTimeout(() => iframe.remove(), 2000);
    });
  }
Dmitry Nogin
la source
génial, mais pour certaines raisons, les fichiers ne sont pas téléchargés. Pour moi, la raison semble que la page se recharge après l'exécution du script, semble être la raison pour laquelle les fichiers ne sont pas téléchargés. Un indice sur ce que je fais de mal?
Chirag Mehta
J'ai plusieurs problèmes avec cette solution. Dans IE depuis que ma fenêtre parent a changé le document.domain, j'ai un accès refusé. Il y a divers articles sur la résolution de cela, mais tous se sentent piratés. Dans Chrome, l'utilisateur reçoit un message d'avertissement indiquant que le site Web tente de télécharger plusieurs fichiers (mais au moins cela fonctionne). Dans Firefox, j'obtiens une boîte de téléchargement différente mais lorsque je clique sur Enregistrer, je n'obtiens pas la boîte de dialogue de sauvegarde du fichier ...
Melanie
Cela n'a pas fonctionné pour moi, car la boîte de dialogue de fichier "bloque" les autres boîtes de dialogue de sauvegarde pour qu'elles apparaissent. Ce que j'ai fait était quelque chose de légèrement hacky - l'action mousemove ne s'enregistre qu'après la disparition de la boîte de dialogue de fichier, alors je l'ai utilisé - mais ce n'est pas testé. Je vais l'ajouter comme une autre réponse.
Karel Bílek
2
Cela fonctionne-t-il dans IE10? J'obtiens: L'objet ne prend pas en charge la propriété ou la méthode 'write'
Hoppe
pourquoi la fonction retournée (fermeture?) activée setTimeout()?
robisrob
34

Cette solution fonctionne sur tous les navigateurs et ne déclenche pas d'avertissements. Plutôt que de créer un iframe, nous créons ici un lien pour chaque fichier. Cela empêche les messages d'avertissement de s'afficher.

Pour gérer la partie en boucle, nous utilisons setTimeout, ce qui est nécessaire pour que cela fonctionne dans IE.

/**
 * Download a list of files.
 * @author speedplane
 */
function download_files(files) {
  function download_next(i) {
    if (i >= files.length) {
      return;
    }
    var a = document.createElement('a');
    a.href = files[i].download;
    a.target = '_parent';
    // Use a.download if available, it prevents plugins from opening.
    if ('download' in a) {
      a.download = files[i].filename;
    }
    // Add a to the doc for click to work.
    (document.body || document.documentElement).appendChild(a);
    if (a.click) {
      a.click(); // The click method is supported by most browsers.
    } else {
      $(a).click(); // Backup using jquery
    }
    // Delete the temporary link.
    a.parentNode.removeChild(a);
    // Download the next file with a small timeout. The timeout is necessary
    // for IE, which will otherwise only download the first file.
    setTimeout(function() {
      download_next(i + 1);
    }, 500);
  }
  // Initiate the first download.
  download_next(0);
}
<script>
  // Here's a live example that downloads three test text files:
  function do_dl() {
    download_files([
      { download: "http://www.nt.az/reg.txt", filename: "regs.txt" },
      { download: "https://www.w3.org/TR/PNG/iso_8859-1.txt", filename: "standards.txt" },
      { download: "http://qiime.org/_static/Examples/File_Formats/Example_Mapping_File.txt", filename: "example.txt" },
    ]);
  };
</script>
<button onclick="do_dl();">Test downloading 3 text files.</button>

speedplane
la source
C'est le seul ici qui a fonctionné pour moi, car je dois soutenir IE. Je vous remercie.
Øystein Amundsen
1
Cette réponse est en or. Un seul qui fonctionne dans tous les navigateurs sans message d'avertissement. Spécialement IE. Brilliant stuff
Mukul Goel
Ne fonctionne pas sous Chrome OSX, il me demande d'autoriser le téléchargement multiple mais même si je le fais, seul le premier fichier est téléchargé et j'ai entendu un montant de "bip" correspondant au nombre de fichiers à télécharger restants
Allan Raquin
2
Button ne fait rien Google Chrome Version 76.0.3809.100 (Official Build) (64-bit).
1934286
1
Le bouton ne fonctionne pas dans le débordement de pile Exécuter l'extrait de code. Browser Crome @speedplane
mb
5

Le moyen le plus simple serait de servir les multiples fichiers regroupés dans un fichier ZIP.

Je suppose que vous pouvez lancer plusieurs téléchargements de fichiers en utilisant un tas d'iframes ou de fenêtres contextuelles, mais du point de vue de la convivialité, un fichier ZIP est toujours meilleur. Qui veut cliquer sur dix boîtes de dialogue «Enregistrer sous» que le navigateur affichera?

Thilo
la source
3
Je me rends compte que votre réponse remonte à 2010, mais de nombreux utilisateurs naviguent avec des smartphones de nos jours, dont certains ne peuvent pas ouvrir les zips par défaut (un copain me dit que son Samsung S4 Active ne peut pas ouvrir les zips).
Hydraxan14
4

Je suis d'accord qu'un fichier zip est une solution plus soignée ... Mais si vous devez pousser plusieurs fichiers, voici la solution que j'ai trouvée. Cela fonctionne dans IE 9 et plus (peut-être la version inférieure aussi - je ne l'ai pas testé), Firefox, Safari et Chrome. Chrome affichera un message à l'utilisateur pour obtenir son accord pour télécharger plusieurs fichiers la première fois que votre site l'utilisera.

function deleteIframe (iframe) {
    iframe.remove(); 
}
function createIFrame (fileURL) {
    var iframe = $('<iframe style="display:none"></iframe>');
    iframe[0].src= fileURL;
    $('body').append(iframe);
    timeout(deleteIframe, 60000, iframe);             
 }
 // This function allows to pass parameters to the function in a timeout that are 
 // frozen and that works in IE9
 function timeout(func, time) {
      var args = [];
      if (arguments.length >2) {
           args = Array.prototype.slice.call(arguments, 2);
      }
      return setTimeout(function(){ return func.apply(null, args); }, time);
 }
 // IE will process only the first one if we put no delay
 var wait = (isIE ? 1000 : 0);
 for (var i = 0; i < files.length; i++) {  
      timeout(createIFrame, wait*i, files[i]);
 }

Le seul effet secondaire de cette technique est que l'utilisateur verra un délai entre la soumission et l'affichage de la boîte de dialogue de téléchargement. Pour minimiser cet effet, je vous suggère d'utiliser la technique décrite ici et sur cette question Détecter quand le navigateur reçoit un téléchargement de fichier qui consiste à placer un cookie avec votre fichier pour savoir qu'il a commencé le téléchargement. Vous devrez vérifier ce cookie côté client et l'envoyer côté serveur. N'oubliez pas de définir le chemin approprié pour votre cookie ou vous ne le verrez peut-être pas. Vous devrez également adapter la solution pour le téléchargement de plusieurs fichiers.

Mélanie
la source
4

Une version jQuery de l'iframe répond:

function download(files) {
    $.each(files, function(key, value) {
        $('<iframe></iframe>')
            .hide()
            .attr('src', value)
            .appendTo($('body'))
            .load(function() {
                var that = this;
                setTimeout(function() {
                    $(that).remove();
                }, 100);
            });
    });
}
Yirmiyahu Fischer
la source
Chacun cherche un tableau. Cela fonctionnera: download(['http://nogin.info/cv.doc','http://nogin.info/cv.doc']);Cependant, cela ne fonctionne pas pour le téléchargement de fichiers image.
tehlivi
3

Solution angulaire:

HTML

    <!doctype html>
    <html ng-app='app'>
        <head>
            <title>
            </title>
            <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
            <link rel="stylesheet" href="style.css">
        </head>
        <body ng-cloack>        
            <div class="container" ng-controller='FirstCtrl'>           
              <table class="table table-bordered table-downloads">
                <thead>
                  <tr>
                    <th>Select</th>
                    <th>File name</th>
                    <th>Downloads</th>
                  </tr>
                </thead>
                <tbody>
                  <tr ng-repeat = 'tableData in tableDatas'>
                    <td>
                        <div class="checkbox">
                          <input type="checkbox" name="{{tableData.name}}" id="{{tableData.name}}" value="{{tableData.name}}" ng-model= 'tableData.checked' ng-change="selected()">
                        </div>
                    </td>
                    <td>{{tableData.fileName}}</td>
                    <td>
                        <a target="_self" id="download-{{tableData.name}}" ng-href="{{tableData.filePath}}" class="btn btn-success pull-right downloadable" download>download</a>
                    </td>
                  </tr>              
                </tbody>
              </table>
                <a class="btn btn-success pull-right" ng-click='downloadAll()'>download selected</a>

                <p>{{selectedone}}</p>
            </div>
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
            <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
            <script src="script.js"></script>
        </body>
    </html>

app.js

var app = angular.module('app', []);            
app.controller('FirstCtrl', ['$scope','$http', '$filter', function($scope, $http, $filter){

$scope.tableDatas = [
    {name: 'value1', fileName:'file1', filePath: 'data/file1.txt', selected: true},
    {name: 'value2', fileName:'file2', filePath: 'data/file2.txt', selected: true},
    {name: 'value3', fileName:'file3', filePath: 'data/file3.txt', selected: false},
    {name: 'value4', fileName:'file4', filePath: 'data/file4.txt', selected: true},
    {name: 'value5', fileName:'file5', filePath: 'data/file5.txt', selected: true},
    {name: 'value6', fileName:'file6', filePath: 'data/file6.txt', selected: false},
  ];  
$scope.application = [];   

$scope.selected = function() {
    $scope.application = $filter('filter')($scope.tableDatas, {
      checked: true
    });
}

$scope.downloadAll = function(){
    $scope.selectedone = [];     
    angular.forEach($scope.application,function(val){
       $scope.selectedone.push(val.name);
       $scope.id = val.name;        
       angular.element('#'+val.name).closest('tr').find('.downloadable')[0].click();
    });
}         


}]);

exemple de travail: https://plnkr.co/edit/XynXRS7c742JPfCA3IpE?p=preview

suresh
la source
1

Pour améliorer la réponse de @Dmitry Nogin: cela a fonctionné dans mon cas.

Cependant, il n'a pas été testé, car je ne suis pas sûr du fonctionnement du dialogue de fichier sur diverses combinaisons OS / navigateur. (Ainsi wiki communautaire.)

<script>
$('#download').click(function () {
    download(['http://www.arcelormittal.com/ostrava/doc/cv.doc', 
              'http://www.arcelormittal.com/ostrava/doc/cv.doc']);
});

var download = function (ar) {
    var prevfun=function(){};
    ar.forEach(function(address) {  
        var pp=prevfun;
        var fun=function() {
                var iframe = $('<iframe style="visibility: collapse;"></iframe>');
                $('body').append(iframe);
                var content = iframe[0].contentDocument;
                var form = '<form action="' + address + '" method="POST"></form>';
                content.write(form);
                $(form).submit();
                setTimeout(function() {    
                    $(document).one('mousemove', function() { //<--slightly hacky!
                        iframe.remove();
                        pp();
                    });
                },2000);
        }
        prevfun=fun; 
      });
      prevfun();   
}
</script>
Karel Bílek
la source
1

Cela fonctionne dans tous les navigateurs (IE11, Firefox, Edge, Chrome et Chrome Mobile) Mes documents sont dans plusieurs éléments sélectionnés. Les navigateurs semblent avoir des problèmes lorsque vous essayez de le faire trop vite ... J'ai donc utilisé un délai d'attente.

//user clicks a download button to download all selected documents
$('#downloadDocumentsButton').click(function () {
    var interval = 1000;
    //select elements have class name of "document"
    $('.document').each(function (index, element) {
        var doc = $(element).val();
        if (doc) {
            setTimeout(function () {
                window.location = doc;
            }, interval * (index + 1));
        }
    });
});

C'est une solution qui utilise les promesses:

 function downloadDocs(docs) {
        docs[0].then(function (result) {
            if (result.web) {
                window.open(result.doc);
            }
            else {
                window.location = result.doc;
            }
            if (docs.length > 1) {
                setTimeout(function () { return downloadDocs(docs.slice(1)); }, 2000);
            }
        });
    }

 $('#downloadDocumentsButton').click(function () {
        var files = [];
        $('.document').each(function (index, element) {
            var doc = $(element).val();
            var ext = doc.split('.')[doc.split('.').length - 1];

            if (doc && $.inArray(ext, docTypes) > -1) {
                files.unshift(Promise.resolve({ doc: doc, web: false }));
            }
            else if (doc && ($.inArray(ext, webTypes) > -1 || ext.includes('?'))) {
                files.push(Promise.resolve({ doc: doc, web: true }));
            }
        });

        downloadDocs(files);
    });
Peintre Zach
la source
1

De loin la solution la plus simple (au moins dans ubuntu / linux):

  • créer un fichier texte avec les URL des fichiers à télécharger (ie file.txt)
  • placez le 'file.txt' dans le répertoire où vous souhaitez télécharger les fichiers
  • ouvrez le terminal dans le répertoire de téléchargement du lin précédent
  • téléchargez les fichiers avec la commande 'wget -i file.txt'

Fonctionne comme un charme.

Martijn
la source
Je ne comprends pas pourquoi cela est rejeté. Cela fonctionne parfaitement, merci beaucoup.
Martin Fürholz
1

Pour résoudre ce problème, j'ai créé une bibliothèque JS pour diffuser plusieurs fichiers directement dans un zip côté client. La principale caractéristique unique est qu'il n'a pas de limite de taille de la mémoire (tout est diffusé) ni de format zip (il utilise zip64 si le contenu est supérieur à 4 Go).

Comme il ne fait pas de compression, il est également très performant.

Trouvez "downzip" sur npm ou github !

DebboR
la source
1

Le script suivant a fait ce travail avec élégance.

var urls = [
'https://images.pexels.com/photos/432360/pexels-photo-432360.jpeg',
'https://images.pexels.com/photos/39899/rose-red-tea-rose-regatta-39899.jpeg'
];

function downloadAll(urls) {


  for (var i = 0; i < urls.length; i++) {
    forceDownload(urls[i], urls[i].substring(urls[i].lastIndexOf('/')+1,urls[i].length))
  }
}
function forceDownload(url, fileName){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";
    xhr.onload = function(){
        var urlCreator = window.URL || window.webkitURL;
        var imageUrl = urlCreator.createObjectURL(this.response);
        var tag = document.createElement('a');
        tag.href = imageUrl;
        tag.download = fileName;
        document.body.appendChild(tag);
        tag.click();
        document.body.removeChild(tag);
    }
    xhr.send();
}
Shyam Narayan
la source
0

Je cherche une solution pour ce faire, mais décompresser les fichiers en javascript n'était pas aussi propre que je le souhaitais. J'ai décidé d'encapsuler les fichiers dans un seul fichier SVG.

Si vous avez les fichiers stockés sur le serveur (ce n'est pas le cas), vous pouvez simplement définir le href dans le SVG.

Dans mon cas, je vais convertir les fichiers en base64 et les intégrer dans le SVG.

Edit: Le SVG fonctionnait très bien. Si vous ne souhaitez télécharger que les fichiers, le format ZIP peut être préférable. Si vous allez afficher les fichiers, SVG semble supérieur.

VecteurVortec
la source
0

Lors de l'utilisation de composants Ajax, il est possible de démarrer plusieurs téléchargements. Par conséquent, vous devez utiliser https://cwiki.apache.org/confluence/display/WICKET/AJAX+update+and+file+download+in+one+blow

Ajoutez une instance d'AJAXDownload à votre page ou autre. Créez un AjaxButton et remplacez onSubmit. Créez un AbstractAjaxTimerBehavior et lancez le téléchargement.

        button = new AjaxButton("button2") {

        private static final long serialVersionUID = 1L;

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form)
        {
            MultiSitePage.this.info(this);
            target.add(form);

            form.add(new AbstractAjaxTimerBehavior(Duration.milliseconds(1)) {

                @Override
                protected void onTimer(AjaxRequestTarget target) {
                    download.initiate(target);
                }

            });     
        }

Bon téléchargement!

kleenxcoder
la source
javascrpt?!?!?!?!?!
bluejayke le
0

Sous le code fonctionne à 100%.

Étape 1 : collez le code ci-dessous dans le fichier index.html

<!DOCTYPE html>
<html ng-app="ang">

<head>
    <title>Angular Test</title>
    <meta charset="utf-8" />
</head>

<body>
    <div ng-controller="myController">
        <button ng-click="files()">Download All</button>
    </div>

    <script src="angular.min.js"></script>
    <script src="index.js"></script>
</body>

</html>

Étape 2 : Collez le code ci-dessous dans le fichier index.js

"use strict";

var x = angular.module('ang', []);

    x.controller('myController', function ($scope, $http) {
        var arr = [
            {file:"http://localhost/angularProject/w3logo.jpg", fileName: "imageone"},
            {file:"http://localhost/angularProject/cv.doc", fileName: "imagetwo"},
            {file:"http://localhost/angularProject/91.png", fileName: "imagethree"}
        ];

        $scope.files = function() {
            angular.forEach(arr, function(val, key) {
                $http.get(val.file)
                .then(function onSuccess(response) {
                    console.log('res', response);
                    var link = document.createElement('a');
                    link.setAttribute('download', val.fileName);
                    link.setAttribute('href', val.file);
                    link.style.display = 'none';
                    document.body.appendChild(link);
                    link.click(); 
                    document.body.removeChild(link);
                })
                .catch(function onError(error) {
                    console.log('error', error);
                })
            })
        };
    });

REMARQUE : assurez-vous que les trois fichiers à télécharger seront placés dans le même dossier avec les fichiers angularProject / index.html ou angularProject / index.js .

solanki ...
la source
do u rilly malaxer ayng [le dernier maître de l'air] ular pour thuis / ???
bluejayke le
0

Obtenir la liste des URL avec l'appel ajax, puis utiliser le plugin jquery pour télécharger plusieurs fichiers en parallèle.

  $.ajax({
        type: "POST",
        url: URL,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        data: data,
        async: true,
        cache: false,
        beforeSend: function () {
            blockUI("body");
        },
        complete: function () { unblockUI("body"); },
        success: function (data) {
           //here data --> contains list of urls with comma seperated
            var listUrls= data.DownloadFilePaths.split(',');
            listUrls.forEach(function (url) {
                $.fileDownload(url);
            });
            return false; 
        },
        error: function (result) {
            $('#mdlNoDataExist').modal('show');
        }

    });
Ali
la source
0

Voici comment je fais cela. J'ouvre plusieurs ZIP mais aussi d'autres types de données (j'exporte le projet en PDF et en même temps de nombreux ZIP avec document).

Je copie juste une partie de mon code. L'appel à partir d'un bouton dans une liste:

$url_pdf = "pdf.php?id=7";
$url_zip1 = "zip.php?id=8";
$url_zip2 = "zip.php?id=9";
$btn_pdf = "<a href=\"javascript:;\" onClick=\"return open_multiple('','".$url_pdf.",".$url_zip1.",".$url_zip2."');\">\n";
$btn_pdf .= "<img src=\"../../../images/icones/pdf.png\" alt=\"Ver\">\n";
$btn_pdf .= "</a>\n"

Donc un appel basique à une routine JS (règles Vanilla!). voici la routine JS:

 function open_multiple(base,url_publication)
 {
     // URL of pages to open are coma separated
     tab_url = url_publication.split(",");
     var nb = tab_url.length;
     // Loop against URL    
     for (var x = 0; x < nb; x++)
     {
        window.open(tab_url[x]);
      }

     // Base is the dest of the caller page as
     // sometimes I need it to refresh
     if (base != "")
      {
        window.location.href  = base;
      }
   }

L'astuce est de NE PAS donner le lien direct du fichier ZIP mais de l'envoyer au navigateur. Comme ça:

  $type_mime = "application/zip, application/x-compressed-zip";
 $the_mime = "Content-type: ".$type_mime;
 $tdoc_size = filesize ($the_zip_path);
 $the_length = "Content-Length: " . $tdoc_size;
 $tdoc_nom = "Pesquisa.zip";
 $the_content_disposition = "Content-Disposition: attachment; filename=\"".$tdoc_nom."\"";

  header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
  header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");   // Date in the past
  header($the_mime);
  header($the_length);
  header($the_content_disposition);

  // Clear the cache or some "sh..." will be added
  ob_clean();
  flush();
  readfile($the_zip_path);
  exit();
Peter
la source
-1
           <p class="style1">



<a onclick="downloadAll(window.links)">Balance Sheet Year 2014-2015</a>

</p>

<script>
 var links = [
  'pdfs/IMG.pdf',
  'pdfs/IMG_0001.pdf',
 'pdfs/IMG_0002.pdf',
 'pdfs/IMG_0003.pdf',
'pdfs/IMG_0004.pdf',
'pdfs/IMG_0005.pdf',
 'pdfs/IMG_0006.pdf'

];

function downloadAll(urls) {
  var link = document.createElement('a');

  link.setAttribute('download','Balance Sheet Year 2014-2015');
  link.style.display = 'none';

  document.body.appendChild(link);

  for (var i = 0; i < urls.length; i++) {
    link.setAttribute('href', urls[i]);
    link.click();
  }

  document.body.removeChild(link);
}
</script>

la source