2012-01-28 42 views
11

Tôi có trình xử lý chung Document.ashx tạo tài liệu Word ngay lập tức bằng cách đọc thông tin từ chuỗi truy vấn như thế này Document.ashx?clientid=123&documentid=10 và hoạt động hoàn hảo.Tải xuống nhiều tệp mà không cần sử dụng tệp Zip

Tôi cần tạo giao diện có danh sách hộp kiểm và nút Download All. Ý tưởng tốt nhất tôi đã có cho đến nay là sử dụng một cái gì đó như thế này để thực hiện cuộc gọi đến người xử lý.

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

Chrome và Firefox xử lý như mong đợi, mặc dù IE9 nhắc người dùng hỏi xem họ có muốn lưu tệp đầu tiên hay không nhưng bỏ qua các tệp sau.

Làm cách nào để bắt đầu tải xuống nhiều tệp từ ứng dụng khách?

Đây là trang web mạng nội bộ để các tệp luôn được tạo trong ~ 1 giây, người dùng sẽ chọn ~ 3-5 tài liệu cùng một lúc. Đại đa số người dùng đang sử dụng IE9. Tôi có thể nói với mọi người rằng họ phải sử dụng Firefox hoặc Chrome nhưng tôi muốn tìm một giải pháp hoạt động trong tất cả các trình duyệt hiện đại.

Tôi không muốn tạo phía máy chủ tệp zip vì sau đó chúng luôn phải giải nén nó trước tiên (điều này sẽ quá khó để một số người hiểu) và làm chậm chúng xuống.

+0

Tôi sẽ thử một cái gì đó như [này] (http://stackoverflow.com/a/4168965/585552) – Greg

Trả lời

10

Vì vậy, đây là propably overkill nhưng làm việc trong IE9, FF7 và Chrome 16:

Lấy cảm hứng từ this SO post

jQuery Plugins:

C# trong handler:

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

Nó phụ thuộc vào thành công của cuộc gọi đầu tiên. Điều gì sẽ xảy ra nếu nó không thành công như thế nào nó sẽ đi trước và gọi downloadFile cho tiếp theo? –

0

Điều này có thể hoặc không giải quyết được vấn đề của bạn, nhưng bạn đang gặp phải lỗi phổ biến ở đây. Iframe không phải là thẻ tự đóng. Nhiều trình duyệt sẽ không phân tích cú pháp html này một cách chính xác. Cố gắng làm cho nó

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

Ngoài ra, bạn cách muốn thử phụ thêm mỗi iframe một cách độc lập, như các trình duyệt có thể không được công nhận các khung một cách chính xác khi được bổ sung cùng một lúc:

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

Sử dụng 2 Các câu lệnh '$ .append()' hoạt động tốt hơn (Chrome không đưa ra cảnh báo tải xuống nhiều tệp) nhưng nó vẫn không hoạt động trong IE9 (nó chỉ nhận ra tệp đầu tiên) – Greg

5

jQuery plugin mà sẽ làm việc cho bạn:

github.com/biesiad/multiDownload

+0

Chrome vẫn cung cấp cho bạn thanh màu vàng có nội dung "Trang web này đang cố gắng tải xuống nhiều tệp. Bạn có muốn cho phép điều này không?" sau khi tải xuống tệp đầu tiên. http://dl.dropbox.com/u/3115379/screengrab_20120719101330.png – Greg

+0

Vâng .. bạn đang cố tải xuống nhiều tệp. Thanh màu vàng là đúng. Nếu bạn muốn tránh nó, bạn có thể thêm sự chậm trễ hơn giữa các lần tải xuống. Kiểm tra tùy chọn 'chậm trễ'. – biesiad

+0

tôi đã đặt hình ảnh thay vì tar.zip trong thử nghiệm github của bạn và không hoạt động trên phiên bản mới nhất của chrome – shareef

0

Tôi biết đây là một câu hỏi cũ, nhưng tôi đã có vấn đề này thời gian gần đây và tạo ra giải pháp này mà phù hợp nhất với nhu cầu của tôi (tôi không muốn sử dụng bất kỳ cookie nào và muốn mã đơn giản nhất có thể).Trong mã sau:

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 

Sau đây là các chức năng 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); 
} 

Đưa DownloadFile (id) bên trong một vòng lặp hoạt động tốt.

Về cơ bản, tôi thấy chrome hoạt động tốt với việc xử lý iFrames, nhưng IE không (tôi đang sử dụng IE9). Điều này đã làm việc cho tôi trên Crome v26, FF v19, IE9.

0

Bạn có thể gọi để tải về trong một vòng lặp javascript như thế này:

<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> 
Các vấn đề liên quan