ดาวน์โหลดไฟล์หลายไฟล์ด้วยการดำเนินการเดียว


109

ฉันไม่แน่ใจว่าเป็นไปได้หรือไม่โดยใช้เทคโนโลยีเว็บมาตรฐาน

ฉันต้องการให้ผู้ใช้สามารถดาวน์โหลดไฟล์หลายไฟล์ในการดำเนินการเดียว นั่นคือคลิกกล่องกาเครื่องหมายถัดจากไฟล์จากนั้นรับไฟล์ทั้งหมดที่ถูกเลือก

เป็นไปได้ไหม - ถ้าเป็นเช่นนั้นคุณแนะนำกลยุทธ์พื้นฐานอย่างไร ฉันรู้ว่าฉันสามารถใช้เทคโนโลยีดาวหางเพื่อสร้างเหตุการณ์ฝั่งเซิร์ฟเวอร์ที่เรียกใช้ HttpResponse แต่ฉันหวังว่าจะมีวิธีที่ง่ายกว่านี้

คำตอบ:


60

HTTP ไม่รองรับการดาวน์โหลดมากกว่าหนึ่งไฟล์พร้อมกัน

มีสองวิธีแก้ไข:

  • เปิด x จำนวนหน้าต่างเพื่อเริ่มการดาวน์โหลดไฟล์ (สามารถทำได้ด้วย JavaScript)
  • โซลูชันที่ต้องการสร้างสคริปต์เพื่อบีบอัดไฟล์

39
เหตุใดไฟล์ zip จึงเป็นโซลูชันที่ต้องการ จะสร้างขั้นตอนพิเศษสำหรับผู้ใช้ (การคลายซิป)
เครื่องบินเร็ว

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 ยังคงเป็นจากDmitry Nogin ดังกล่าวข้างต้น
MatějPokorný

1
@tehlivi - ฉันเจอสิ่งเดียวกัน เพิ่มlink.setAttribute('download',filename)วงใน ซึ่งจะช่วยให้คุณสามารถตั้งชื่อไฟล์ได้ตามต้องการ นอกจากนี้ฉันเชื่อว่าต้องเป็นชื่อไฟล์เท่านั้นไม่รวม URL ฉันลงเอยด้วยการส่งอาร์เรย์สองอาร์เรย์: อันหนึ่งมี URL แบบเต็มและอีกอันมีชื่อไฟล์
PhilMDev

7
มันไม่ทำงานอย่างถูกต้องใน Chrome V75, Windows 10: Minecraft.jarเฉพาะไฟล์ที่ดาวน์โหลดเป็น
andreivictor

54

คุณสามารถสร้างชุดของ iframe ที่ซ่อนไว้ชั่วคราวเริ่มการดาวน์โหลดโดย GET หรือ POST ในนั้นรอให้การดาวน์โหลดเริ่มต้นและลบ iframe:

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

ยอดเยี่ยม แต่ด้วยเหตุผลบางประการไฟล์ไม่ได้รับการดาวน์โหลด สำหรับฉันแล้วเหตุผลที่ดูเหมือนว่าหน้าโหลดซ้ำหลังจากเรียกใช้สคริปต์ดูเหมือนว่าจะเป็นสาเหตุที่ไฟล์ไม่ได้รับการดาวน์โหลด มีเงื่อนงำอะไรที่ฉันทำผิด?
Chirag Mehta

ฉันมีปัญหาหลายอย่างเกี่ยวกับวิธีแก้ปัญหานี้ ใน IE เนื่องจากหน้าต่างหลักของฉันเปลี่ยน document.domain ฉันจึงถูกปฏิเสธการเข้าถึง มีโพสต์มากมายเกี่ยวกับการแก้ไขปัญหานี้ แต่ทุกคนรู้สึกแฮ็ค ใน Chrome ผู้ใช้จะได้รับข้อความแจ้งเตือนโดยแจ้งว่าเว็บไซต์พยายามที่จะโหลดไฟล์หลายไฟล์ (แต่ก็ใช้ได้น้อยที่สุด) ใน Firefox ฉันได้รับกล่อง dowload ที่แตกต่างกัน แต่เมื่อฉันคลิกบันทึกฉันไม่ได้รับกล่องโต้ตอบบันทึกไฟล์ ...
Melanie

สิ่งนี้ไม่ได้ผลสำหรับฉันเพราะกล่องโต้ตอบไฟล์ "บล็อก" กล่องโต้ตอบบันทึกอื่น ๆ จะปรากฏขึ้น สิ่งที่ฉันทำมีบางอย่างที่แฮ็กเล็กน้อยการดำเนินการของ mousemove จะลงทะเบียนหลังจากกล่องโต้ตอบไฟล์หายไปเท่านั้นดังนั้นฉันจึงใช้สิ่งนั้น - แต่ยังไม่ได้ทดสอบ ผมจะเพิ่มเป็นอีกคำตอบ
Karel Bílek

2
ใช้งานได้ใน IE10 หรือไม่ ฉันได้รับ: Object ไม่รองรับคุณสมบัติหรือเมธอด 'write'
Hoppe

เหตุผลที่ฟังก์ชั่นกลับ (ปิด?) บน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 เป็นพิเศษ สิ่งที่ยอดเยี่ยม
Mukul Goel

ไม่ทำงานใน Chrome OSX ระบบขอให้ฉันอนุญาตการดาวน์โหลดหลายครั้ง แต่แม้ว่าฉันจะดาวน์โหลดเพียงไฟล์แรกเท่านั้นและฉันได้ยินเสียง "บี๊บ" จำนวนหนึ่งที่สอดคล้องกับจำนวนไฟล์ที่จะดาวน์โหลดที่เหลือ
Allan Raquin

2
ปุ่มไม่ทำอะไรGoogle Chrome Version 76.0.3809.100 (Official Build) (64-bit)เลย
1934286

1
ปุ่มไม่ทำงานในสแต็กล้นเรียกใช้ข้อมูลโค้ด Browser Crome @speedplane
mb

5

วิธีที่ง่ายที่สุดคือให้บริการไฟล์หลายไฟล์ที่รวมอยู่ในไฟล์ ZIP

ฉันคิดว่าคุณสามารถเริ่มการดาวน์โหลดไฟล์หลายไฟล์โดยใช้ iframe หรือป๊อปอัปจำนวนมาก แต่จากมุมมองด้านการใช้งานไฟล์ ZIP ยังดีกว่า ใครต้องการคลิกผ่านกล่องโต้ตอบ "บันทึกเป็น" สิบรายการที่เบราว์เซอร์จะเปิดขึ้นมา


3
ฉันรู้ว่าคำตอบของคุณย้อนกลับไปในปี 2010 แต่ในปัจจุบันผู้ใช้จำนวนมากกำลังท่องเว็บด้วยสมาร์ทโฟนซึ่งบางคนไม่สามารถเปิดซิปได้ตามค่าเริ่มต้น (เพื่อนบอกฉันว่า Samsung S4 Active ของเขาไม่สามารถเปิดซิปได้)
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]);
 }

ผลข้างเคียงเดียวของเทคนิคนี้คือผู้ใช้จะเห็นความล่าช้าระหว่างการส่งและกล่องโต้ตอบการดาวน์โหลดที่แสดง เพื่อลดเอฟเฟกต์นี้ฉันขอแนะนำให้คุณใช้เทคนิคที่อธิบายไว้ที่นี่และในคำถามนี้ตรวจหาเมื่อเบราว์เซอร์ได้รับการดาวน์โหลดไฟล์ที่ประกอบด้วยการตั้งค่าคุกกี้กับไฟล์ของคุณเพื่อให้ทราบว่าได้เริ่มดาวน์โหลดแล้ว คุณจะต้องตรวจสอบคุกกี้นี้ในฝั่งไคลเอ็นต์และส่งไปที่ฝั่งเซิร์ฟเวอร์ อย่าลืมกำหนดเส้นทางที่เหมาะสมสำหรับคุกกี้ของคุณไม่เช่นนั้นคุณอาจมองไม่เห็น คุณจะต้องปรับวิธีแก้ปัญหาสำหรับการดาวน์โหลดไฟล์หลายไฟล์


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: สิ่งนี้ใช้ได้ผลในกรณีของฉัน

อย่างไรก็ตามยังไม่ได้ทดสอบเนื่องจากฉันไม่แน่ใจว่าบทสนทนาของไฟล์ทำงานอย่างไรในชุดค่าผสม OS / เบราว์เซอร์ต่างๆ (ดังนั้นชุมชน wiki)

<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' ในไดเร็กทอรีที่คุณต้องการดาวน์โหลดไฟล์
  • เปิดเทอร์มินัลในไดเร็กทอรีดาวน์โหลดจาก lin ก่อนหน้า
  • ดาวน์โหลดไฟล์ด้วยคำสั่ง 'wget -i file.txt'

ใช้งานได้เหมือนมีเสน่ห์


ฉันไม่เข้าใจว่าเหตุใดจึงมีการลดคะแนนลง มันทำงานได้อย่างสมบูรณ์ขอบคุณมาก
Martin Fürholz

1

ในการแก้ปัญหานี้ฉันได้สร้างไลบรารี JS เพื่อสตรีมไฟล์หลายไฟล์โดยตรงไปยัง zip ที่ฝั่งไคลเอ็นต์ คุณสมบัติพิเศษหลักคือไม่มีการ จำกัด ขนาดจากหน่วยความจำ (ทุกอย่างถูกสตรีม) หรือรูปแบบ zip (ใช้ zip64 หากเนื้อหามากกว่า 4GB)

เนื่องจากไม่ได้ทำการบีบอัดจึงมีประสิทธิภาพมากเช่นกัน

ค้นหา "downzip" บนnpmหรือgithub !


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

ฉันกำลังมองหาวิธีแก้ปัญหานี้ แต่การคลายซิปไฟล์ในจาวาสคริปต์นั้นไม่สะอาดเท่าที่ฉันชอบ ฉันตัดสินใจที่จะห่อหุ้มไฟล์เป็นไฟล์ SVG ไฟล์เดียว

หากคุณมีไฟล์ที่เก็บไว้บนเซิร์ฟเวอร์ (ฉันไม่มี) คุณสามารถตั้งค่า href ใน SVG ได้

ในกรณีของฉันฉันจะแปลงไฟล์เป็น base64 และฝังลงใน SVG

แก้ไข: SVG ทำงานได้ดีมาก หากคุณจะดาวน์โหลดไฟล์เท่านั้น ZIP อาจดีกว่า หากคุณกำลังจะแสดงไฟล์ SVG จะดูดีกว่า


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

            });     
        }

มีความสุขในการดาวน์โหลด!


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ไฟล์


คุณ rilly นวด ayng [airbender คนสุดท้าย] ular for thuis / ???
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 หลายไฟล์ แต่ยังรวมถึงข้อมูลประเภทอื่น ๆ ด้วย (ฉันส่งออก projet เป็น 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>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.