2012-01-28 4 views
11

Ho un gestore generico Document.ashx che crea documenti Word in tempo leggendo le informazioni dalla querystring come questa Document.ashx?clientid=123&documentid=10 e funziona perfettamente.Download di più file senza l'uso di file zip

Devo creare un'interfaccia con un elenco di checkbox e un pulsante Download All. L'idea migliore che ho avuto finora è di usare qualcosa del genere per effettuare le chiamate al gestore.

$("body").append("<iframe src='Document.ashx?clientid=123&documentid=10'></iframe> 
        <iframe src='Document.ashx?clientid=123&documentid=11'></iframe>") 

Chrome e Firefox gestire questo come previsto, se IE9 richiede all'utente di chiedere se vogliono salvare il primo file, ma ignora i seguenti file.

Come avviare il download di più file dal client?

Questo è per un sito intranet in modo che i file vengano sempre generati in ~ 1 secondo, gli utenti selezionerebbero ~ 3-5 documenti alla volta. La stragrande maggioranza degli utenti utilizza IE9. Posso dire a tutti che devono usare Firefox o Chrome, ma preferirei trovare una soluzione che funzioni in tutti i browser moderni.

Non voglio creare un file server zip perché poi devono sempre decomprimerlo prima (che sarà troppo difficile da capire per alcuni) e li rallenta.

+0

sarò provare qualcosa di simile [questo] (http://stackoverflow.com/a/4168965/585552) – Greg

risposta

10

Quindi questa è stata riordinata eccessivo, ma lavora a IE9, FF7, e Chrome 16:

Ispirato this SO post

jQuery Plugin:

C# nel gestore:

public void ProcessRequest (HttpContext context) { 

    ... 

    if (!string.IsNullOrEmpty(context.Request.QueryString["downloadid"])) 
      Response.Cookies[context.Request.QueryString["downloadid"]].Value = "complete"; 
} 

JavaScript/jQuery:

function downloadFile(url, downloadid) { 
    //set a cookie with a unique download id 
    $.cookie(downloadid, 'pending', { path: '/' }); 

    //create a new url 
    var newurl = $.param.querystring(url, { downloadid: downloadid }); 

    //append an iframe with new url 
    $("body").append("<iframe style='height:0;width:0;' data-downloadid='" + downloadid + "' src='" + newurl + "'></iframe>"); 
} 

function downloadComplete(downloadid) { 
    //check if download is pending 
    return $.cookie(downloadid) == "complete"; 
} 

function downloadManager(arrDownloads) { 
    //loop through download items backwards 
    var allComplete = false; 
    for (var i = arrDownloads.length; i > 0; i--) { 
     if (downloadComplete(arrDownloads[i - 1].downloadid)) { 
      //download the next one if it exists 
      if (i == arrDownloads.length) { 
       allComplete = true; 
      } 
      else { 
       downloadFile(arrDownloads[i].url, arrDownloads[i].downloadid); 
      } 
      //stop checking for completed downloads 
      break; 
     } 
    } 

    if (allComplete) { 
     //remove cookies 
     for (var i = arrDownloads.length; i > 0; i--) { 
      $.cookie(arrDownloads[i - 1].downloadid, null, { path: '/' }); 
     } 

     //remove iframes 
     $("iframe[data-downloadid]").remove(); 
    } 
    else { 
     setTimeout("downloadManager(" + JSON.stringify(arrDownloads) + ");", 500); 
    } 
} 

function downloadFiles(arrurls) { 
    var arrDownloads = []; 

    for (var i = 0; i < arrurls.length; i++) { 
     var item = new Object(); 
     item.url = arrurls[i]; 
     item.downloadid = newGuid(); 
     arrDownloads.push(item); 
    } 

    //start the first download 
    downloadFile(arrDownloads[0].url, arrDownloads[0].downloadid); 
    //initiate the manager 
    downloadManager(arrDownloads); 
} 

$(function() { 
    var arrurls = []; 
    arrurls.push("Document.ashx?clientid=123&documentid=10"); 
    arrurls.push("Document.ashx?clientid=123&documentid=11"); 
    arrurls.push("Document.ashx?clientid=123&documentid=12"); 
    arrurls.push("Document.ashx?clientid=123&documentid=13"); 
    arrurls.push("Document.ashx?clientid=123&documentid=14"); 
    downloadFiles(arrurls); 
}); 
+0

Dipende dal successo della prima chiamata. Cosa succede se non è riuscito come andrà avanti e chiamare downloadfile per il prossimo? –

0

Questo può o non può risolvere il problema, ma si sta commettendo un errore comune qui. Gli iframe non sono tag che si chiudono automaticamente. Molti browser non analizzeranno correttamente questo html. Prova rendendo

$("body").append("<iframe src='Document.ashx?clientid=123&documentid=10'>If you can read this, please use a newer browser</iframe> 
        <iframe src='Document.ashx?clientid=123&documentid=11'>If you can read this, please use a newer browser</iframe>") 

Inoltre, è modo vuole provare aggiungendo ogni iframe in modo indipendente, come i browser non possono essere riconoscendo i fotogrammi in modo corretto quando viene aggiunto tutto in una volta:

$("body").append("<iframe src='Document.ashx?clientid=123&documentid=10'>If you can read this, please use a newer browser</iframe>"); 
$("body").append("<iframe src='Document.ashx?clientid=123&documentid=10'>If you can read this, please use a newer browser</iframe>"); 
+3

Utilizzando 2 'Le dichiarazioni $ .append()' hanno funzionato meglio (Chrome non ha lanciato un avviso sul download di più file) ma non funziona ancora in IE9 (riconosce solo il primo file) – Greg

5

jQuery plugin che farà il lavoro per voi:

github.com/biesiad/multiDownload

+0

Chrome ti fornisce ancora una barra gialla che dice "Questo sito sta tentando di scaricare più file. Vuoi permetterlo?" dopo aver scaricato il primo file. http://dl.dropbox.com/u/3115379/screengrab_20120719101330.png – Greg

+0

Bene .. stai provando a scaricare più file. La barra gialla è giusta. Se vuoi evitarlo, potresti aggiungere più ritardo tra i download. Controlla l'opzione 'ritardo'. – biesiad

+0

ho messo immagini invece di tar.zip nel tuo test github e non ho funzionato su chrome ultima versione – shareef

0

So che questa è una vecchia questione, ma non ho avuto questo problema di recente e ha creato questa soluzione che meglio si adatta alle mie esigenze (non volevo utilizzare qualsiasi cookie e voleva che il codice fosse il più semplice possibile).Nel codice dietro:

Protected Sub DownloadFile(fileId As String) 
    If Request.Browser.Browser = "Chrome" Then 
     'open iframes dynamically for multiple downloads 
     ClientScript.RegisterStartupScript(Me.GetType(), fileId, _ 
              "<script language='javascript'>createIframeForDownloadHandler('" & fileId & "');</script>") 
    Else 
     'open windows for multiple downloads 
     ClientScript.RegisterStartupScript(Me.GetType(), fileId, _ 
              "<script language='javascript'>openWindowForDownloadHandler('" & fileId & "');</script>") 
    End If 
End Sub 

Qui ci sono le funzioni JavaScript:

function openWindowForDownloadHandler(fileId) { 
    //open a new window. setting height and width foces new window as opposed to new tab 
    window.open('FileShareDownloadHandler.ashx?id=' + fileId, '_blank', 'width=100,height=100,left=0,top=0'); 
} 

function createIframeForDownloadHandler(fileId) { 
    var element = document.createElement("iframe"); 
    element.setAttribute('id', 'myframe' + fileId); 
    element.setAttribute('style', 'display:none;'); 
    element.setAttribute('src', 'FileShareDownloadHandler.ashx?id=' + fileId); 
    document.body.appendChild(element); 
} 

Putting DownloadFile (id) all'interno di un ciclo funziona bene.

Fondamentalmente, ho trovato che chrome funziona bene con la gestione degli iFrame, ma IE non lo fa (sto usando IE9). Questo ha funzionato per me su Crome v26, FF v19, IE9.

0

È possibile chiamare per scaricare in un ciclo javascript come questo:

<a id="downloadAll" href="#">Download All</a> 

<script> 
var downloadSelected = $('a#downloadSelected'); 
var doc_ids = ['10', '11']; 
for (var i in doc_ids) { 
    var uri = 'Document.ashx?clientid=123&documentid=' + doc_ids[i]; 
    var iframe = $("<iframe/>").attr({ 
        src: uri, 
        style: "visibility:hidden;display:none" 
       }).appendTo(downloadAll); 
} 
</script>