当前位置主页 > 资料库 > 前端教程 > HTML5教程 | HTML5 File API

HTML5教程 | HTML5 File API

09-12

HTML5 File API允许页面使用Javascript来调用和处理本地文件系统的文件。通过HTML5 File API我们可以使用javascript来处理某个文件,例如对文件进行比较,编码,加密,更新等操作。由于涉及到本地文件的操作,HTML5 File API的安全问题也是被人们关注的重点问题。本文将介绍如何使用HTML5 File API,以及HTML5 File API的安全性问题。

HTML5 File API的核心对象

HTML5 File API包含以下的核心对象:

  • FileList
  • File
  • Blob
  • FileReader

File对象代表本地文件系统中的一个文件。

FileList对象代表本地文件系统中的一组文件。例如在某个目录或文件夹中的所有文件。

Blob对象代表一个二进制大型对象(BLOB),BLOB是本地文件系统中的单个文件的数据。

下面将会接收如何使用这些File API对象。

选择一个文件

在HTML5 File API可以处理本地文件系统中的一个文件之前,用户需要执行一个选择文件的操作。由于安全的原因,通常是通过HTML的<input type="file">元素来选择文件,就像下面的示例代码:

<input type="file" >                              
                            

仅仅有input元素是不够的,我们还需要添加一个onchange的事件监听,下面是示例代码:

<input type="file" onchange="readFiles(event)">

文件输入域input[type='file']包含一个“浏览”按钮,当用户点击这个按钮的时候,就会弹出一个文件对话框。在这个文件对话框中,用户可以对本地的文件进行选择,被选择的文件将会在onchange事件监听的event对象中作为参数传入。

选择多个文件

要使用户能够选择多个文件,可以在<input>元素中添加一个multiple属性,下面是一个示例代码:

<input type="file" onchange="readFiles(event)" multiple>
通过拖放选择文件

我们可以将HTML5 file API和HTML5元素拖放相结合来选择文件。这种选择文件的方式需要实现用户从本地电脑的文件系统中(在浏览器之外)拖拽一个文件到浏览器的HTML页面指定的放置区域。HTML页面能通过javascript来检测是否有文件被放置在指定的区域。

下面的代码是如何设置一个放置区域HTML元素,使它能够检测到是否有文件放置到它上面。

<div id="fileDropZone" >
    请拖拽文件到这里
</div>                              
                            
<script>
    function drop(event) {
        evt.stopPropagation();
        evt.preventDefault();

        var fileList = event.dataTransfer.files;

        // 通过fileList接收文件
     }

    function dragOver(evt) {
        evt.stopPropagation();
        evt.preventDefault();
        evt.dataTransfer.dropEffect = 'copy';
    }

    var dropZone = document.getElementById("fileDropZone");
    dropZone.addEventListener("dragover", dragOver, false);
    dropZone.addEventListener("drop"    , drop    , false);
</script>                              
                            

dragOver()drop()函数设置放置区域HTML元素的拖和放事件监听。

当一个文件被放置在放置区域的时候,drop()函数将被调用。被放置在放置区域的文件列表可以通过event.dataTransfer.files对象(一个FileList对象)来找到。

dragOver()函数是可选的。它仅用于文件被拖拽时的一个副本。它通过一个文件图标来显示。

剩下的代码是访问选择的文件,它和通过input元素来选择一个文件后的操作是相同的。

在实际操作中最好为放置区域HTML元素设置一些样式,使用户能够明确的指定这里是可以拖拽放置的区域。

访问被选择的文件

当用户选择一个或多个文件之后,有两种方式访问这些被选择的文件。

第一种访问被选择文件的方式是访问input元素的files属性。下面是一个示例代码:

var inputField = document.getElementById('theFileInput');
    
var selectedFiles = inputField.files;

for(var i=0; i<selectedFiles.length; i++) {
    var file = selectedFiles[i);    
}                              
                            

第二种访问被选择文件的方式是通过input元素的onchange事件监听。被选择的文件会作为event对象的参数被传入。下面是一个示例代码:

<input type="file" onchange="readFiles(event)" multiple>
<script>
function readFiles(event) {
    var fileList = event.target.files;
}
</script>                              
                            

event.target.files对象是一个FileList对象。它包含一组被选择的文件(File对象)。如果只有一个文件被选择,这个列表中就只有一个对象。下面的实例代码说明了如何去迭代一组文件列表。

<input type="file" onchange="readFiles(event)" multiple>                             
                            
<script>
function readFiles(event) {
    var fileList = event.target.files;

    for(var i=0; i < fileList.length; i++ ) {
        var file = fileList[i];     // a File object
        console.log("i: " + i + " - " + file.name);
    }
}
</script>                              
                            

FileList是一组File对象列表。File对象用于访问文件。在下面的介绍中,你会看到通过javascript来加载文件的不同方法。

通过FileReader来加载文件

当用户选择了一个文件后。我们得到了一个文件的引用(例如通过onchange事件)。我们可以通过FileReader来读取这个文件。FileReader对象有下面的一些方法可以用于读取文件:

  • readAsText()
  • readAsDataUrl()
  • readAsArrayBuffer()

上面的方法都使用一个File对象或Blob对象作为参数。

File对象可以从FileList对象中获取,前面已经介绍过。

Blob对象代表部分或整个文件。你可以从File对象中创建一个Blob对象,下面是示例代码:

var theFile = fileList[0]; // 从FileList获取一个File对象

var from = 3;
var to   = 9;
var blob = theFile.slice(from, to);   // 创建Blob对象                              
                            

上面的代码用slice方法来分割一个文件,Blob对象从文件的第3个字节开始,到第8个字节结束(不包含第9个字节)。

创建一个FileReader

要使用FileReader你先要创建FileReader对象。创建FileReader对象的方法如下:

var reader = new FileReader();                              
                            

FileReader对象被创建之后,你就可以使用它来读取文件了。

将一个文件作为文本来加载

要将一个文件作为文本来加载,你可以使用HTML5 file API的FileReader对象。下面是一个示例代码:

<input type="file" onchange="readFiles(event)" multiple>
<script>
function readFiles(event) {
    var fileList = event.target.files;

    for(var i=0; i < fileList.length; i++ ) {
        loadAsText(fileList[i]);
    }
}

function loadAsText(theFile) {
    var reader = new FileReader();

    reader.onload = function(loadedEvent) {
        // 返回包含被加载的文件
        console.log(loadedEvent.target.result);
    }
    reader.readAsText(theFile);
}
</script>                              
                            

文件在loadAsText()函数中被加载。

上面的代码首先创建了一个FileReader对象,然后在FileReader对象上调用onload事件,这个事件在文件被加载完毕之后被调用。

接着,FileReader中的readAsText()函数被调用,它使用一个File对象作为参数。这里是加载文件的开始,当文件加载完毕,onload事件将被调用。

加载部分文件

你可以只加载一个文件的某一部分,而不是整个文件。下面的loadAsTextSlice()函数展示了如何使用HTML5 file API来加载文件的一部分内容。

function loadAsTextSlice(theFile) {
    var start = 3;
    var stop  = 9;
    var blob = theFile.slice(start, stop);

    var reader = new FileReader();
    reader.onload = function(loadedEvent) {
        console.log(loadedEvent.target.result);
    }
    reader.readAsText(blob);
}                             
                            

上面的例子通过File对象的slice()方法创建了一个Blob对象。然后创建一个FileReader对象,然后在它上面添加onload()事件监听。

接下来FileReader对象的readAsText()被调用,它的参数是一个Bolb对象。这是读取文件的开始,当这部分文件被读取完毕,onload()方法就会被调用。要获取这部分被读取的文件,可以通过loadedEvent.target.result来获取。

通过Data URL来加载文件

我们还可以通过data URL来加载一个文件。典型的例子是一个图片的数据,我们可以读取图片的数据,然后将这些数据设置到图片的src属性中。下面的loadAsUrl()函数展示了如何使用HTML5 file API将文件作为data URL进行读取。

function loadAsUrl(theFile) {
    var reader = new FileReader();

    reader.onload = function(loadedEvent) {
        var image = document.getElementById("theImage");
        image.setAttribute("src", loadedEvent.target.result);
    }

    reader.readAsDataURL(theFile);
}                              
                            

上面的代码中首先创建了一个FileReader对象,然后在这个FileReader对象上设置onload()事件监听。当文件加载完毕,onload()事件就会被触发。onload()函数的参数是loadedEvent,通过这个参数,我们可以获取被编码为data URL的文件数据,使用的是event.target.result属性。在获取了编码的文件数据之后,我们就可以把这些数据设置为图片src属性的值,这样图片就会被显示出来。

通过ArrayBuffer来加载文件

FileReader对象的readAsArrayBuffer()函数可以用于作为ArrayBuffer来读取文件数据。一个ArrayBuffer代表任意长度的缓冲区数据。你不能够直接在ArrayBuffer中操作数据,你必须创建一个DataView对象,该对象可以接收任意类型的ArrayBuffer数据。

下面是一个例子:

function loadAsUrl(theFile) {
    var reader = new FileReader();

    reader.onload = function(loadedEvent) {
        var arrayBuffer =  loadedEvent.target.result;
        var dataView = new DataView(arrayBuffer, 0, arrayBuffer.byteLength);

        var byte = dataView.getUint8(0);   //获取ArrayBuffer的第一个字节

        //... 处理余下的dataView ...
    }

    reader.readAsArrayBuffer(theFile);
}                             
                            

关于DataView对象的更多资料,可以参考这里

跟踪文件加载的进程

HTML5 file API允许我们跟踪文件加载的进程,这意味着我们可以知道当前文件加载了多少。要跟踪文件加载的进程,可以在FileReader对象上添加onprogress事件监听。

var reader = new FileReader();

reader.onprogress = function(progressEvent) {

    if(progressEvent.lengthComputable) {
        var percentLoaded = Math.round( (
                progressEvent.loaded * 100) / progressEvent.total );
    }
    console.log("total: " + progressEvent.total + ", loaded: "
              + progressEvent.loaded + "(" + percentLoaded + "%)");
}                              
                            

传入到onprogress事件中的progressEvent参数包含一个布尔值的属性lengthComputable。如果这个属性的值为true,你就可以计算文件已经被加载了多少,具体操作就像上面代码的样子。

浏览器对HTML5 File API的支持

浏览器对HTML5 File API的支持可以通过caniuse.com来查看。IE8和IE9不支持它,其它的现代浏览器都支持HTML5 File API。但是有一些浏览器不支持File对象的构造函数,这其实对使用没有什么影响。

返回HTML5教程目录
Previous:
上一篇:HTML5教程 | HTML5 time元素
Next:
下一篇:HTML5教程 | HTML5 History API
返回顶部