使用HTML 5 File API(2)

by Vivid 1. 八月 2012 05:34

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:N120812701
出刊日期:2012/8/1 (週三)

本文延續《使用HTML 5 File API(1)》一文,將介紹HTML 5中提供的File API,因為不同的瀏覽器對於HTML 5的支援程度不同,因此文中的範例以Chrome進行測試,但程式碼不見得可以在其它瀏覽器中正確的執行。

使用FileReader物件讀取檔案

若要讀取檔案中的內容,可以利用FileReader物件,檔案讀取的動作採非同步方式。要讀取檔案可以利用幾個方法:

  • readAsText:以文字方式讀檔案內容,放到result屬性,預設使用的編碼方式是「UTF-8」。
  • readAsDataURL:讀取到的內容會編碼成data URL,放到result屬性。
  • readAsArrayBuffer:result屬性會包含一個ArrayBuffer物件。
  • readAsBinaryString:以二進位方式讀檔案內容,放到result屬性。

參考下列使用readAsText方法讀取檔案內容的範例:

<!DOCTYPE html >
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head>
    <title> </title>
    <script type = "text/javascript" >
        function ProcessFile( e ) {
            var file = document.getElementById('file').files[0] ;
            if (file) {
                var reader = new FileReader();
                reader.onload = function ( event ) {                                      
                    var txt = event.target.result ;                
                    document.getElementById('result').innerHTML = txt;
                    };
              }
            reader.readAsText( file ); 
            }
        function contentLoaded() {
            document.getElementById( 'file' ).addEventListener( 'change',
ProcessFile , false );
        }
        window.addEventListener( "DOMContentLoaded" , contentLoaded , false );
    </script>
</head>
<body>
    <input type = "file" id = "file" name = "file" />
    <div id = "result"> </div>
</body>
</html>

readAsText方法需要傳入Blob,也就是您要讀取的檔案。readAsText方法有一個選擇性的參數,可以設定編碼。在FileReader的Load事件中,利用event.target.result取出檔案的內容,然後顯示在div中,請參考圖1所示:

clip_image002

圖 1:使用FileReader物件讀取檔案。

FileReader事件

FileReader讀取檔案時會觸發onloadstart、onprogress、onload、onabort、onerror與onloadend等事件,您也可以攔截這些事件,例如以下範例,攔截了開始載入檔案時觸發的onloadstart事件,以及在檔案載入完成時觸發的onloadend事件:

<!DOCTYPE html >
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head>
    <title> </title>
    <script type = "text/javascript">
        var result = document.getElementById("result");
        function ProcessFile( e ) {
            var file = document.getElementById( 'file' ).files[0];
            if (file) {
                var reader = new FileReader();

                reader.onload = function ( event ) {
                    var txt = event.target.result;
                    document.getElementById('result').innerHTML = txt;
                };
                reader.onloadstart = function ( event ) {
                    alert( "開始載入" );
                };
                reader.onloadend = function ( event ) {
                    alert( "載入完成" );
                    reader.close();
                };
                reader.readAsText( file,"UTF-8" );
            }
        }

        function contentLoaded () {
            document.getElementById( 'file' ).addEventListener( 'change' ,
ProcessFile , false );
        }
        window.addEventListener( "DOMContentLoaded" , contentLoaded , false );
    </script>
</head>
<body>
    <input type = "file" id = "file" name = "file"  />
    <div id = "result"> </div>
</body>
</html>

FileReader onprogress事件

FileReader onprogress事件可以用來監控讀取的過程,也很適合在此事件中提供一些訊息給使用者,像是檔案讀取的百分比。例如以下程式範例,在onporgress事件觸發時,利用loaded屬性取得已讀取的檔案位元組數,與記錄檔案總位元組數的total屬性來計算出檔案讀取的百分比,然後顯示在網頁上。

 

<!DOCTYPE html >
<html xmlns =" http://www.w3.org/1999/xhtml" >
<head>
    <title> </title>
    <script type = "text/javascript" >
        function ProcessFile( e ) {
            var result = document.getElementById("result");
            var file = document.getElementById('file').files[0];
            if (file) {
                var reader = new FileReader();
                reader.onprogress = function ( event ) {
                    if ( event.lengthComputable ) {
                        var per = Math.round( (event.loaded * 100) / event.total) ;
                        result.innerHTML = per + '%';
                    };
                }
                reader.onload = function ( event ) {
                    var txt = event.target.result;
                    result.innerHTML = '100%';
                };
                reader.readAsBinaryString( file );
            }
        }
        function contentLoaded () {
            document.getElementById( 'file' ).addEventListener( 'change' ,
ProcessFile , false );
        }
        window.addEventListener( "DOMContentLoaded" , contentLoaded , false );
    </script>
</head>
<body>
    <input type = "file" id = "file" name = "file" />
    <div id = "result"> </div>
</body>
</html>

 

 

使用progress標籤顯示檔案讀取進度

HTML 5新增一個progress標籤,可以用來表示某項工作完成的進度,這個進度會隨著時間改變。因此它很適合搭配FileReader來顯示檔案讀取進度。progress標籤包含兩個attribute,一為Value代表目前工作的進度;其二為Max代表工作的最大值。我們將上一個範例的程式碼修改如下:

 

<!DOCTYPE html >
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head>
    <title> </title>
    <script type = "text/javascript" >
        function ProcessFile( e ) {
            var result = document.getElementById( "result" );
            var file = document.getElementById('file').files[0];
            if ( file ) {
                var reader = new FileReader();
                reader.onprogress = function ( event ) {
                    if ( event.lengthComputable ) {
                        var per = Math.round( (event.loaded * 100) / event.total) ;
                        result.innerHTML = '<progress max="100" value="' + per + '" ></progress>';
                    };
                }
                reader.onload = function ( event ) {
                    var txt = event.target.result;
                    result.innerHTML = '<progress max="100" value="100" ></progress>';
                };
                reader.readAsBinaryString( file );
            }
        }
        function contentLoaded () {
            document.getElementById( 'file' ).addEventListener( 'change' ,
ProcessFile , false );
        }
        window.addEventListener( "DOMContentLoaded" , contentLoaded , false );
</script>
</head>
<body>
 
    <input type = "file" id = "file" name = "file" />
    <div id = "result"> </div>
</body>
</html>

 

 

此範例執行的結果請參考圖2所示。

clip_image004

圖 2:使用progress標籤顯示檔案讀取進度。

使用readAsDataURL讀取圖檔

FileReader物件的readAsDataURL方法可以將讀取到的檔案編碼成Data URL。Data URL是一項特殊的技術,可以將資料(例如圖片)內嵌在網頁之中,不用放到外部檔案。使用Data URL的好處是,您不需要額外再發出一個HTTP 請求到伺服端取得額外的資料;而缺點便是,網頁的大小可能會變大。它適合應用在內嵌小圖片,不建議將大圖檔編碼成Data URL來使用。您的圖檔不能夠超過瀏覽器限定的大小,否則無法讀取圖檔。

參考以下使用readAsDataURL讀取圖檔範例:

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head>
    <title> </title>
    <script type = "text/javascript" >
        function ProcessFile( e ) {   
            var file = document.getElementById('file').files[0];
            if (file) {
               
                var reader = new FileReader();
                reader.onload = function ( event ) {                 
                    var txt = event.target.result;
                    document.getElementById("result").innerHTML = txt;
                    };
              }
            reader.readAsDataURL( file );
            }
        function contentLoaded () {
            document.getElementById('file').addEventListener( 'change' ,
ProcessFile , false );
        }
        window.addEventListener( "DOMContentLoaded" , contentLoaded , false );
    </script>
</head>
<body>
   請選取一個圖檔: <input type = "file" id = "file" name = "file"  />
   <div id = "result"> </div>
</body>
</html>

此範例執行的結果請參考圖3所示,readAsDataURL方法會使用base-64進行編碼,編碼的資料由data字串開始,後面跟隨的是MIME type,然後再加上base64字串,逗號之後就是編碼過的圖檔的內容。

clip_image006

圖 3:使用readAsDataURL讀取圖檔。

 

使用Img顯示圖檔

若想要將讀取出來的圖檔,直接顯示在網頁上,您可以透過JavaScript建立一個<img>標籤,再設定src屬性為Data URL,再將<img>標籤加入DOM之中,例如以下範例所示:

 

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head>
    <title> </title>
    <script type = "text/javascript" >
        function ProcessFile( e ) {   
            var file = document.getElementById('file').files[0];
            if ( file ) {
               
                var reader = new FileReader();
                reader.onload = function ( event ) {                 
                    var txt = event.target.result;
                    var img = document.createElement("img");
                    img.src = txt;
                    document.getElementById("result").appendChild( img );
                    };
              }
            reader.readAsDataURL( file );
            }
        function contentLoaded() {
            document.getElementById('file').addEventListener( 'change' ,
ProcessFile , false );
        }
        window.addEventListener( "DOMContentLoaded" , contentLoaded , false );
    </script>
</head>
<body>
   請選取一個圖檔: <input type = "file" id = "file" name = "file"  />
   <div id = "result"> </div>
</body>
</html>

 

 

此範例執行的結果請參考圖4所示。

clip_image008

圖 4:使用Img顯示圖檔。

 

讀取部分檔案

有時想要讀取的檔案太大,想要分段進行讀取;或者只想要讀取檔案部分的內容,這時您可以將檔案切割,根據瀏覽器的不同,可以使用以下方法:

  • webkitSlice:適用於支援Webkit引擎的瀏覽器,如Chrome。
  • mozSlice:適用於Firefox。

這兩個方法要傳入開始的位元組索引,以及結尾的位元組索引,索引以0開始。以下程式範例以FileReader物件的readAsBinaryString方法來讀取檔案,只讀取檔案的第三個位元組讀取到第六個位元組:

<!DOCTYPE html>
<html xmlns ="http://www.w3.org/1999/xhtml" >
<head>
    <title> </title>
    <script type = "text/javascript" >
        function ProcessFile( e ) {

            var file = document.getElementById( 'file' ).files[0];
            if ( file ) {
                var reader = new FileReader ();
                reader.onload = function ( event ) {
                    var txt = event.target.result;
                    document.getElementById( "result" ).innerHTML = txt;
                };
            }

            if ( file.webkitSlice ) {
                var blob = file.webkitSlice( 2, 4 );
            } else if ( file.mozSlice ) {
                var blob = file.mozSlice( 2, 4 );
            }
            reader.readAsBinaryString( blob );
        }

        function contentLoaded() {
            document.getElementById( 'file' ).addEventListener( 'change' ,
ProcessFile , false );
        }
        window.addEventListener( "DOMContentLoaded", contentLoaded , false );
    </script>
</head>
<body>
    <input type = "file" id = "file" name = "file" />
    <div id = "result" > </div>
</body>
</html>

Tags:

.NET Magazine國際中文電子雜誌 | HTML | 許薰尹Vivid Hsu

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List