<%@ Page Language="C#" %>
<!DOCTYPE html>
 
<script runat="server">
  void Page_Load(object sender, EventArgs e)
  {
    if (Request["mode"] == "download")
    {
      if (Request["err"] == "1")
        //To simulate failed download
        Response.Write("<html><body>Failed to Download File!</body></html>");
      else
      {
        Response.AddHeader("content-disposition",
          "attachment;filename=text.txt");
        Response.ContentType = "application/octet-stream";
        Response.Write("Darkthread Test");
      }
      Response.End();
    }
  }
</script>
 
<html>
<head runat="server">
  <title>Download Test</title>
  <script type="text/javascript" 
    src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.js"></script>
  <script type="text/javascript">
    $(function () {
      $(":button").click(function () {
        var dlLink = "Download.aspx?mode=download&err=" +
               $("#err:checked").length;
        switch (this.id) {
          case "b1":
            window.open(dlLink);
            break;
          case "b2":
            location.href = dlLink;
            break;
          case "b3":
            var $ifrm = $("<iframe style='display:none' />');
            $ifrm.attr("src", dlLink);
            $ifrm.appendTo("body");
            $ifrm.load(function () {
              //if the download link return a page
              //load event will be triggered
              $("body").append(
                "<div>Failed to download <i>'" + dlLink + "'</i>!");
            });
            break;
        }
      });
    });
  </script>
  <style type="text/css">
    .btn input
    {
      display: block;
      width: 200px; height: 30px; 
      margin: 10px;
      text-align: center; 
    }
  </style>
</head>
<body>
  <form id="form1" runat="server">
  <input type="checkbox" id="err" />Failed Download
  <div class='btn'>
  <input type="button" id="b1" value="Download with window.open" />
  <input type="button" id="b2" value="Download with location.href" />
  <input type="button" id="b3" value="Download with hidden iframe" />  
  </div>
  <div id="msg"></div>
  </form>
</body>
</html>

以下是簡單的分析比較:

  1. window.open() 
    缺點: 下載時畫面會如PostBack般閃一下 
    下載出錯時,錯誤訊息會顯示在另一個分頁或新視窗。
  2. location.href法 
    缺點: 出錯時,錯誤訊息會置換掉現有頁面 
    下載路徑會出現在瀏覽記錄中
  3. iframe法 
    缺點: 出錯時訊息被隱藏在iframe中,預設不會呈現(我有嘗試找到解法,見後段說明)

比較之下,個人偏好iframe法,至於無法偵測下載出錯的問題,我發現<iframe>有個特性: 當src指向的連結是一般網頁,$(iframe).load()事件會被觸發,指向下載檔案連結時則不會。利用此差異,我們可以在load()事件中加 入下載失敗提醒,因為load()一旦被執行就代表下載失敗。原本另一個想法是try catch所有錯誤並傳回一段Javascript,彈出alert()或修改父頁面元素顯示資訊,但這個做法對HTTP 404或500錯誤無效,比較之下,load()事件法還是較好的解決方案。




reference:
http://blog.darkthread.net/post-2011-08-12-ajax-download-with-iframe.aspx

arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()