透過Javascript觸發檔案下載

使用者在點擊網頁元素後啟動檔案下載的方法有好幾種,我做了一個ASP.NET網頁一次測試window.open(), location.href, 隱藏iframe等三種方法,同時還加個Checkbox以模擬下載失敗顯示錯誤訊息網頁的情境。

<%@ 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()事件法還是較好的解決方案。

歡迎推文分享:
Published 12 August 2011 06:54 PM 由 Jeffrey
Filed under: ,
Views: 65,172



意見

# 艾里克斯 said on 16 August, 2011 01:10 AM

您好, 這個題目蠻有意思的:p

不過如果遇到有些人設定直接在 ie 中檢視 office 文件, 那麼在 iframe 中開啟會不會就看不到了呢:) ?

# Jeffrey said on 17 August, 2011 03:19 AM

to 艾里克斯, 1) Office自2007版起就不再支援由IE內直接檢視文件(REF: support.microsoft.com/.../927009) 2) 針對Office 2007以前的版本,Response.ContentType = "application/octet-stream";可迫使瀏覽器將其視為一般下載檔案而不是Office文件

# 嵐曦 said on 05 September, 2012 09:28 PM

J大您好,

想請教一個window.open()問題

我有一個index.htm

想在點下後開啟一個無工作列的乾淨視窗

我的寫法是

<script language="JavaScript">

window.open("home.htm","","width="+screen.width+",height="+screen.height +",left=0,top=0");

  window.open('','_parent','');  

  window.opener = null;

  window.close();

</script>

透過index呼叫home來另開視窗

但在chrome和firefox下都會把home.htm攔截掉

請問有辦法避免這個問題或是有其它呈現方式嗎??

感謝您!!

# Jeffrey said on 06 September, 2012 05:44 AM

to 嵐曦, 新版瀏覽器已不太允許程式自發性開啟視窗的行為(被廣告視窗搞怕了),只有在一些條件下才會允許(例如: 使用者點擊連結、調整快顯封鎖程式設定... 等)。細節可以參考這篇文章: blog2.darkthread.net/post-2011-07-12-showmodaldialog-and-popup-blocker.aspx

# Arthur said on 28 October, 2015 10:48 AM

从没有做过这个东西,今天被老板要求做出来,在网上找了很久,我觉得在你这里找到了答案。特地来感谢你。

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<August 2011>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication