2012-01-28 3 views
11

У меня есть общий обработчик Document.ashx, который создает документы Word на лету, читая информацию из строки запроса Document.ashx?clientid=123&documentid=10, и она отлично работает.Загрузите несколько файлов без использования Zip-файла

Мне нужно создать интерфейс со списком флажков и кнопку Download All. Лучшая идея, которую я использовал до сих пор, - это использовать что-то подобное, чтобы вызвать вызовы обработчику.

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

Chrome и Firefox справиться с этим, как и ожидалось, хотя IE9 предлагает пользователю спросить, если они хотят, чтобы сохранить первый файл, но игнорирует следующие файлы.

Как инициировать загрузку нескольких файлов с клиента?

Это для сайта интрасети, поэтому файлы всегда генерируются в ~ 1 секунду, пользователи будут выбирать ~ 3-5 документов за раз. Подавляющее большинство пользователей используют IE9. Я могу сказать всем, что им нужно использовать Firefox или Chrome, но я бы скорее нашел решение, которое работает во всех современных браузерах.

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

+0

Я хочу попробовать что-то вроде [это] (http://stackoverflow.com/a/4168965/585552) – Greg

ответ

10

Так это Propably излишества, но работает в IE9, FF7 и Chrome 16:

this SO post Вдохновленный

JQuery плагинов:

C# в обработчике:

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

Это зависит от успеха первого вызова. Что делать, если он не работает, как он будет идти дальше и вызвать downloadFile для следующего? –

0

Это может быть или не решить вашу проблему, но вы делаете общую ошибку здесь. Ифрагмы не являются самозакрывающимися тегами. Многие браузеры не будут правильно разбирать этот html. Попробуйте сделать это

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

Кроме того, вы путь хотите попробовать, добавляя каждый IFRAME независимо друг от друга, так как браузеры не могут признать кадры правильно, когда добавляются все сразу:

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

Используя 2 Операторы '$ .append()' работали лучше (Chrome не выдавал предупреждения о загрузке нескольких файлов), но он все еще не работает в IE9 (он распознает только первый файл) – Greg

5

JQuery плагин, который будет делать работу за вас:

github.com/biesiad/multiDownload

+0

Chrome по-прежнему дает вам желтую полоску, в которой говорится: «Этот сайт пытается загрузить несколько файлов. Вы хотите разрешить это?» после загрузки первого файла. http://dl.dropbox.com/u/3115379/screengrab_20120719101330.png – Greg

+0

Ну .. вы пытаетесь загрузить несколько файлов. Желтый бар прав. Если вы хотите этого избежать, вы можете добавить дополнительную задержку между загрузками. Проверьте вариант «задержка». – biesiad

+0

Я поставил изображения вместо tar.zip в ваш тест github и не работал на последней версии Chrome. – shareef

0

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

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 

Вот 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); 
} 

Ввод DownloadFile (ID) внутри петля работает хорошо.

В принципе, я нашел, что хром хорошо работает с обработкой iFrames, но IE не работает (я использую IE9). Это работает для меня на Crome v26, FF v19, IE9.

0

Вы можете позвонить, чтобы загрузить в яваскрипта цикле, как это:

<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> 
Смежные вопросы