Скачивание нескольких файлов одним действием

109

Я не уверен, возможно ли это с использованием стандартных веб-технологий.

Я хочу, чтобы пользователь мог загружать несколько файлов за одно действие. То есть установите флажки рядом с файлами, а затем получите все файлы, которые были проверены.

Возможно ли - если да, то какую базовую стратегию вы порекомендуете. Я знаю, что могу использовать технологию комет для создания событий на стороне сервера, которые запускают HttpResponse, но я надеюсь, что есть более простой способ.

Анкур
источник

Ответы:

60

HTTP не поддерживает одновременную загрузку более одного файла.

Есть два решения:

  • Откройте x количество окон, чтобы начать загрузку файлов (это будет сделано с помощью JavaScript)
  • предпочтительное решение создать скрипт для архивирования файлов
Яков Релкин
источник
39
Почему zip-файл является предпочтительным решением? Это создает дополнительный шаг для пользователя (разархивирование).
Speedplane
7
Эта страница содержит javascript, который создает ZIP-файл. Посмотрите на страницу, на которой есть отличный пример. stuk.github.io/jszip
Netsi1964
Третий способ - инкапсулировать файлы в файл SVG. Если файлы отображаются в браузере, SVG кажется лучшим способом.
VectorVortec
4
Сам HTTP поддерживает формат составных сообщений. Но браузеры не переносят многостраничные ответы со стороны сервера, но технически в этом нет ничего сложного.
CMCDragonkai
2
Это может быть отличным решением с 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>

Матей Покорный
источник
3
Я работаю со многими типами файлов, включая изображения, и это сработало лучше всего для меня. Однако link.setAttribute('download', null);переименовал все мои файлы в null.
tehlivi
7
Он не работает в IE 11, он загружает только .jar (последний элемент в списке), это было идеальное решение :(
Immutable Brick
1
@AngeloMoreira Да, по крайней мере, это работает в Edge. Если вы попытаетесь загрузить несколько файлов в IE на сайтах MS, например , они вызовут несколько всплывающих окон, поэтому я думаю, что лучшее решение для IE по-прежнему от Дмитрия Ногина выше .
Matěj Pokorný
1
@tehlivi - нашел то же самое. Добавьте link.setAttribute('download',filename)внутреннюю часть петли. Это позволяет вам называть файлы как угодно. Кроме того, я считаю, что это должно быть только имя файла, не включая URL-адрес. В итоге я отправил два массива: один с полным URL-адресом и один только с именем файла.
PhilMDev
7
Он не работает должным образом в Chrome v75, Windows 10: единственный загружаемый файл - это Minecraft.jar.
andreivictor 05
54

Вы можете создать временный набор скрытых фреймов, инициировать загрузку с помощью GET или POST внутри них, дождаться начала загрузки и удалить фреймы:

<!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>

Или без 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);
    });
  }
Дмитрий Ногин
источник
круто, но по некоторым причинам файлы не скачиваются. Мне кажется, причина в том, что страница перезагружается после выполнения скрипта, что, по-видимому, является причиной того, что файлы не загружаются. Есть какие-нибудь подсказки о том, что я делаю неправильно?
Чираг Мехта
У меня есть несколько проблем с этим решением. В IE, поскольку мое родительское окно изменило document.domain, мне отказано в доступе. Есть разные сообщения об исправлении этого, но все они кажутся хакерскими. В Chrome пользователь получает предупреждение о том, что веб-сайт пытается загрузить несколько файлов (но, по крайней мере, это работает). В Firefox у меня другое окно загрузки, но когда я нажимаю «Сохранить», я не получаю диалоговое окно сохранения файла ...
Мелани
У меня это не сработало, потому что диалоговое окно файла «блокирует» появление других диалоговых окон сохранения. То, что я сделал, было немного хакерским - действие mousemove регистрируется только после того, как диалоговое окно файла исчезает, поэтому я использовал его, но он не тестировался. Я добавлю это как еще один ответ.
Карел Билек
2
Это работает в IE10? Я получаю: объект не поддерживает свойство или метод write
Хоппе,
почему возвращенная функция (закрытие?) на setTimeout()?
robisrob
34

Это решение работает во всех браузерах и не вызывает предупреждений. Вместо того, чтобы создаватьiframe , здесь мы создаем ссылку для каждого файла. Это предотвращает появление предупреждающих сообщений.

Для обработки циклической части мы используем setTimeout, что необходимо для работы в 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>

скоростной самолет
источник
Это единственный вариант, который у меня сработал, так как я должен поддерживать IE. Спасибо.
Øystein Amundsen
1
Это золотой ответ. Только тот, который работает во всех браузерах без предупреждения. Специально IE. Блестящий материал
Мукул Гоэль
Не работает в Chrome OSX, он просит меня разрешить несколько загрузок, но даже если я это сделаю, будет загружен только первый файл, и я услышал звуковой сигнал, соответствующий количеству файлов, которые нужно загрузить,
Allan
2
Кнопка ничего не делает Google Chrome Version 76.0.3809.100 (Official Build) (64-bit).
1934286
1
Кнопка не работает при переполнении стека Выполнить фрагмент кода. Browser Crome @speedplane
mb
5

Самый простой способ - использовать несколько файлов, объединенных в ZIP-файл.

Я предполагаю, что вы могли бы инициировать несколько загрузок файлов, используя кучу iframe или всплывающих окон, но с точки зрения удобства использования ZIP-файл все же лучше. Кто захочет просмотреть десять диалоговых окон «Сохранить как», которые откроет браузер?

Тило
источник
3
Я понимаю, что ваш ответ еще в 2010 году, но в настоящее время многие пользователи просматривают страницы со смартфонами, некоторые из которых не могут открывать zip-архивы по умолчанию (приятель сказал мне, что его Samsung S4 Active не может открывать zip-архивы).
Hydraxan14
4

Я согласен, что zip-файл - лучшее решение ... Но если вам нужно отправить несколько файлов, вот решение, которое я придумал. Он работает в IE 9 и новее (возможно, и в более ранней версии - я не тестировал), Firefox, Safari и Chrome. Chrome отобразит сообщение пользователю, чтобы получить его согласие на загрузку нескольких файлов при первом использовании вашего сайта.

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]);
 }

Единственный побочный эффект этого метода заключается в том, что пользователь увидит задержку между отправкой и отображением диалогового окна загрузки. Чтобы свести к минимуму этот эффект, я предлагаю вам использовать технику, описанную здесь и по этому вопросу. Обнаружение, когда браузер получает загрузку файла, которая заключается в установке файла cookie с вашим файлом, чтобы знать, что он начал загрузку. Вам нужно будет проверить этот файл cookie на стороне клиента и отправить его на стороне сервера. Не забудьте указать правильный путь для вашего файла cookie, иначе вы можете его не увидеть. Вам также придется адаптировать решение для загрузки нескольких файлов.

Мелани
источник
4

Версия iframe на jQuery отвечает:

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);
            });
    });
}
Ирмиягу Фишер
источник
Каждый ищет массив. Это будет работать: download(['http://nogin.info/cv.doc','http://nogin.info/cv.doc']);Однако это не работает для загрузки файлов изображений.
tehlivi
3

Угловое решение:

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();
    });
}         


}]);

рабочий пример: https://plnkr.co/edit/XynXRS7c742JPfCA3IpE?p=preview

суреш
источник
1

Чтобы улучшить ответ @Dmitry Nogin: это сработало в моем случае.

Однако он не тестировался, так как я не уверен, как файловый диалог работает в различных комбинациях ОС / браузера. (Таким образом, вики сообщества.)

<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>
Карел Билек
источник
1

Это работает во всех браузерах (IE11, firefox, Edge, Chrome и Chrome Mobile). Мои документы находятся в нескольких выбранных элементах. У браузеров возникают проблемы, когда вы пытаетесь сделать это слишком быстро ... Итак, я использовал тайм-аут.

//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));
        }
    });
});

Это решение, в котором используются обещания:

 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);
    });
Зак Пейнтер
источник
1

Безусловно, самое простое решение (по крайней мере, в ubuntu / linux):

  • создать текстовый файл с URL-адресами файлов для загрузки (например, file.txt)
  • поместите файл file.txt в каталог, в который вы хотите загрузить файлы
  • откройте терминал в каталоге загрузок из предыдущей линки
  • скачать файлы с помощью команды 'wget -i file.txt'

Работает как шарм.

Мартейн
источник
Я не понимаю, почему за это отказывают. Это отлично работает, большое вам спасибо.
Мартин Фюрхольц
1

Чтобы решить эту проблему, я создал JS-библиотеку для потоковой передачи нескольких файлов прямо в zip-архив на стороне клиента. Основная уникальная особенность заключается в том, что он не имеет ограничений по размеру из памяти (все передается в потоковом режиме) или формата zip (он использует zip64, если содержимое превышает 4 ГБ).

Поскольку он не выполняет сжатие, он также очень эффективен.

Найдите его на npm или github !

DebboR
источник
1

Следующий скрипт изящно выполнил эту работу.

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();
}
Шьям Нараян
источник
0

Я ищу решение для этого, но распаковка файлов в javascript не была такой чистой, как мне хотелось. Я решил инкапсулировать файлы в один файл SVG.

Если у вас есть файлы, хранящиеся на сервере (у меня их нет), вы можете просто установить href в SVG.

В моем случае я конвертирую файлы в base64 и вставляю их в SVG.

Изменить: SVG работал очень хорошо. Если вы собираетесь загружать только файлы, лучше использовать ZIP. Если вы собираетесь отображать файлы, то SVG кажется лучше.

ВекторVortec
источник
0

При использовании компонентов Ajax можно запускать несколько загрузок. Поэтому вы должны использовать https://cwiki.apache.org/confluence/display/WICKET/AJAX+update+and+file+download+in+one+blow

Добавьте экземпляр AJAXDownload на свою страницу или что-то еще. Создайте AjaxButton и переопределите onSubmit. Создайте AbstractAjaxTimerBehavior и начните загрузку.

        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);
                }

            });     
        }

Удачной загрузки!

kleenxcoder
источник
javascrpt?!?!?!?!?!
bluejayke,
0

Ниже код 100% рабочий.

Шаг 1. Вставьте код ниже в файл 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>

Шаг 2. Вставьте код ниже в файл 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);
                })
            })
        };
    });

ПРИМЕЧАНИЕ . Убедитесь, что все три файла, которые будут загружены, будут помещены в одну папку вместе с файлами angularProject / index.html или angularProject / index.js .

соланки ...
источник
у рилли месить айнг [последний маг воздуха] улар для туи / ???
bluejayke,
0

Получение списка URL-адресов с помощью вызова ajax, а затем использование плагина jquery для параллельной загрузки нескольких файлов.

  $.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');
        }

    });
Али
источник
0

Вот как я это делаю. Я открываю несколько ZIP, а также другие данные (я экспортирую проект в PDF и одновременно много файлов ZIP с документом).

Я просто копирую прошлую часть своего кода. Вызов от кнопки в списке:

$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"

Итак, простой вызов процедуры JS (ванильные правила!). вот процедура 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;
      }
   }

Уловка состоит в том, чтобы НЕ давать прямую ссылку на ZIP-файл, а отправить его в браузер. Как это:

  $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();
Питер
источник
-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>

источник