前言

在 HTML 文档中 <input type="file"> 标签每出现一次,一个 FileUpload 对象就会被创建。

 

该元素包含一个文本输入字段,用来输入文件名,还有一个按钮,用来打开文件选择对话框以便图形化选择文件。

该元素的 value 属性保存了用户指定的文件的名称,但是当包含一个 file-upload 元素的表单被提交的时候,浏览器会向服务器发送选中的文件的内容而不仅仅是发送文件名。

当用户选择或编辑一个文件名,file-upload 元素触发 onchange 事件句柄。

看个简单例子:

<!-- oscar999  -->  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
  <meta http-equiv="content-type" content="text/html; charset=utf-8">  
  <meta name="author" content="oscar999">  
  <title></title>  
  <script>  
  function  handleFiles(files)  
  {  
    if(files.length)  
    {  
       var file = files[0];  
       var reader = new FileReader();  
       reader.onload = function()  
       {  
           document.getElementById("filecontent").innerHTML = this.result;  
       };  
       reader.readAsText(file);  
    }  
  }  
  </script>  
    
  </head>  
  <body>  
  
  <input type="file" id="file" onchange="handleFiles(this.files)"/>  
  <div id="filecontent"></div>  
  </body>  
</html>  

这里读取一个文件, 显示在div 中。

 

(在IE8 中 无效, this.files 无法读取文件。这个属于html5 的特性)

当选择了一个文件时,就会把包含这个文件的列表(一个FileList对象)作为参数传给handleFiles()函数了。
这个FileList对象类似一个数组,可以知道文件的数目,而它的元素就是File对象了。
从这个File对象可以获取name、size、lastModifiedDate和type等属性。
把这个File对象传给FileReader对象的读取方法,就能读取文件了。

 

 

HTML5 Drag and Drop File

HTML5 支持的File 的操作不仅仅是文件的选择,

在HTML5 之前需要使用 Applet 和 SilverLight 才能达到的文件拖拽功能,在HTML5 中也能轻松的实现,

看代码:

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
  <meta http-equiv="content-type" content="text/html; charset=utf-8">  
  <meta name="author" content="oscar999">  
  <title></title>  
  </head>  
  <body>  
    <div id="dropbox"> Drop Here </div>  
    <div id="filecontent"></div>  
    <script>  
      var dropbox = document.getElementById("dropbox");    
      dropbox.addEventListener("dragenter", dragenter, false);    
      dropbox.addEventListener("dragover", dragover, false);    
      dropbox.addEventListener("drop", drop, false);     
  
    function dragenter(e) {    
        e.stopPropagation();    
        e.preventDefault();    
    }    
  
    function dragover(e) {    
        e.stopPropagation();    
        e.preventDefault();    
    }  
  
    function drop(e) {    
        e.stopPropagation();    
        e.preventDefault();     
        var dt = e.dataTransfer;    
        var files = dt.files;  
        if(files.length)  
        {  
           var file = files[0];  
           var reader = new FileReader();  
           reader.onload = function()  
           {  
               document.getElementById("filecontent").innerHTML = this.result;  
           };  
           reader.readAsText(file);  
        }  
    }   
            
    </script>  
  </body>  
</html>  

这里通过事件对象的 dataTransfer 可以得到文件。

 

 

读取文件内容

在第一个例子中, 我们使用 FileReader类来读取文件的内容,

在 W3C 草案中,File 对象只包含文件名,文件类型等只读属性;FileReader用于内容读取和监控读取状态。

(在firefox 中, 可以直接使用= file.getAsBinary();  读取文件的二进制源码)

FileReader提供的方法包括:

1. readAsBinaryString

2. readAsDataURL

3. readAsText

4. abort

.........

 

以下,举一个 使用 FileReader 将用户选择的图片不通过后台即时显示出来的例子。

function handleFiles(files){  
    for (var i = 0; i < files.length; i++) {  
        var file = files[i];  
        var imageType = /image.*/;  
          
        if (!file.type.match(imageType)) {  
            continue;  
        }  
          
        var img = document.createElement("img");  
        img.classList.add("obj");  
        img.file = file;  
        preview.appendChild(img);  
          
        var reader = new FileReader();  
        reader.onload = (function(aImg){  
            return function(e){  
                aImg.src = e.target.result;  
            };  
        })(img);  
        reader.readAsDataURL(file);  
    }  
}  


 

 

同后端的交互

在一般的HTML  中,使用方式是把file input 放在form 中, 以POST 方式把文件传递到后端。

 

在 HTML5 中, 也可以通过 FileReader 的 readAsBinaryString 方法读取到文件的二进制码,然后通过 XMLHttpRequest 的 sendAsBinary 方法将其发送出去。

var xhr = new XMLHttpRequest();  
xhr.open("POST", "url");  
xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');  
<pre code_snippet_id="422893" snippet_file_name="blog_20140709_4_2106578" class="sh_javascript sh_sourceCode" name="code">xhr<span class="sh_symbol">.</span><span class="sh_function">sendAsBinary</span><span class="sh_symbol">(</span>binaryString<span class="sh_symbol">);</span></pre><br>  


 

 

 

参考

 

 

 

浏览器支持

适用于 Firefox 3.6+ ,Chrome ,部分适用于其他支持 HTML 5 接口的浏览器,完全不适用于 IE8 及以下版本