[转]文件file属性详解
不能直接访问用户计算机中的文件,一直都是Web应用开发中的一大障碍。2000年以前,处理文件的唯一方式就是在表单中加入<input type="file">字段,仅此而已。FileAPI(文件API)的宗旨是为Web开发人员提供一种安全的方式,以便在客户端访问用户计算机中的文件,并更好地对这些文件执行操作。本文将详细介绍文件File API
[注意]IE9-浏览器不支持
File
File API在表单中的文件输入字段的基础上,又添加了一些直接访问文件信息的接口。HTML5在DOM中为文件输入元素添加了一个files集合。在通过文件输入字段选择了一或多个文件时,files集合中将包含一组File对象,每个File对象对应着一个文件。每个File对象都有下列只读属性
name:本地文件系统中的文件名
size:文件的字节大小
type:字符串,文件的MIME类型
lastModifiedDate:字符串,文件上一次被修改的时间
通过侦听change事件并读取files集合就可以知道选择的每个文件的信息
<input type="file" id="file1">
<div id="result"></div>
<script>
file1.onchange = function(){
var data = file1.files[0];
result.innerHTML = '类型:' + data.type + '<br>大小:' + data.size + '(字节)<br>名称:' + data.name + '<br>修改时间:' + data.lastModifiedDate;
}
</script>
【隐藏文件input】
现代浏览器支持隐藏掉默认的的文件输入框<input>元素,使用自定义的界面来充当打开文件选择对话框的按钮。实现起来很简单,只需要使用样式display:none把原本的文件输入框隐藏掉,然后在需要的时候调用它的click()方法就行了
[注意]IE9-浏览器不支持
<input type="file" id="file1" style="display:none">
<button id="btn">按钮</button>
<div id="result"></div>
<script>
btn.onclick = function(){
file1.click();
}
file1.onchange = function(){
result.innerHTML = file1.files[0].name;
}
</script>
FileReader
File API的功能还不止于此,通过它提供的FileReader类型甚至还可以读取文件中的数据
【构造函数】
使用FileReader()构造函数来创建一个FileReader对象
var reader = new FileReader();
【属性】
error:表示在读取文件时发生的错误(只读)
readyState:表明FileReader对象的当前状态,值为状态常量中的一个(只读)
状态常量有以下三个
常量名 值 描述
EMPTY 0 还没有加载任何数据
LOADING 1 数据正在被加载
DONE 2 已完成全部的读取请求
result:表示读取到的文件内容,这个属性只在读取操作完成之后才有效,并且数据的格式取决于读取操作是由哪个方法发起的(只读)
【方法】
FileReader类型实现的是一种异步文件读取机制。可以把FileReader想象成XMLHttpRequest,区别只是它读取的是文件系统,而不是远程服务器。为了读取文件中的数据,FileReader提供了如下几个方法
abort():中止该读取操作
readAsText(file或Blob,encoding):以纯文本形式读取File或Blob对象的内容,将读取到的文本保存在result属性中。第二个参数(可选)用于指定编码类型,默认为UTF-8
readAsDataURL(file或Blob):读取File或Blob对象的内容,并将文件以数据URI(进行Base64编码)的形式保存在result属性中
readAsBinaryString(file或Blob):读取File或Blob对象的内容,并将一个字符串保存在result属性中,字符串中的每个字符表示一字节
readAsArrayBuffer(file或Blob):读取File或Blob对象的内容,并将一个包含文件内容的ArrayBuffer保存在result属性中
[注意]IE浏览器不支持readAsBinaryString()方法
这些读取文件的方法为灵活地处理文件数据提供了极大便利。例如,可以读取图像文件并将其保存为数据URI,以便将其显示给用户,或者为了解析方便,可以将文件读取为文本形式
【事件】
由于读取过程是异步的,因此FileReader也提供了几个事件
onabort:当读取操作被中止时调用
onerror:当读取操作发生错误时调用
onload:当读取操作成功完成时调用
onloadend:当读取操作完成时调用,不管是成功还是失败。该处理程序在onload或者onerror之后调用
onloadstart:当读取操作将要开始之前调用
onprogress:在读取数据过程中周期性调用
在正常情况下,读取文件时,首先触发loadstart事件,此时的readyState为1,result为空
接着,每过50ms左右,就会触发一次progress事件,通过事件对象可以获得与XHR的progress事件相同的信息(属性):lengthComputable、loaded和total。另外,尽管可能没有包含全部数据,但每次progress事件中都可以通过FileReader的result属性读取到文件内容,readyState仍然是1
当文件读取完成时,触发load事件,此时的readyState为2,result为文件内容;如果发生了error事件,就不会发生load事件
<input type="file" id="file1">
<div id="result"></div>
<script>
/*
[loadstart]readyState:1;result:
[progress]readyState:1;result:h3{color: #F44336;}
[load]readyState:2;result:h3{color: #F44336;}
[loadend]readyState:2;result:h3{color: #F44336;}
*/
file1.onchange = function(){
var reader = new FileReader();
reader.readAsText(file1.files[0]);
reader.onloadstart = function(e){
console.log('[loadstart]readyState:' + reader.readyState + ';result:' + reader.result);
}
reader.onload = function(e){
console.log('[load]readyState:' + reader.readyState + ';result:' + reader.result);
}
reader.onloadend = function(e){
console.log('[loadend]readyState:' + reader.readyState + ';result:' + reader.result);
}
reader.onprogress = function(e){
console.log('[progress]readyState:' + reader.readyState + ';result:' + reader.result);
}
}
</script>
由于种种原因无法读取文件,就会触发error事件。触发error事件时,相关的信息将保存到FileReader的error属性中。这个属性中将保存一个对象,该对象只有一个属性code,即错误码。这个错误码是1表示未找到文件,是2表示安全性错误,是3表示读取中断,是4表示文件不可读,是5表示编码错误
reader.onerror = function(){
output.innerHTML = "Could not read file, error code is " + reader.error.code;
};
如果想中断读取过程,可以调用abort()方法,这样就会触发abort事件
在触发load、error或abort事件后,会触发另一个事件loadend。loadend事件发生就意味着已经读取完整个文件,或者读取时发生了错误,或者读取过程被中断
重要的缩略图
使用FileReader对象的 readAsDataURL() 方法完成对文件的读取,再通过 File对象的 type属性 筛选出图片
<img id="uploadPreview" style="width: 100px; height: 100px;" src="data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Csvg%20width%3D%22153%22%20height%3D%22153%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%3Cg%3E%0A%20%20%3Ctitle%3ENo%20image%3C/title%3E%0A%20%20%3Crect%20id%3D%22externRect%22%20height%3D%22150%22%20width%3D%22150%22%20y%3D%221.5%22%20x%3D%221.500024%22%20stroke-width%3D%223%22%20stroke%3D%22%23666666%22%20fill%3D%22%23e1e1e1%22/%3E%0A%20%20%3Ctext%20transform%3D%22matrix%286.66667%2C%200%2C%200%2C%206.66667%2C%20-960.5%2C%20-1099.33%29%22%20xml%3Aspace%3D%22preserve%22%20text-anchor%3D%22middle%22%20font-family%3D%22Fantasy%22%20font-size%3D%2214%22%20id%3D%22questionMark%22%20y%3D%22181.249569%22%20x%3D%22155.549819%22%20stroke-width%3D%220%22%20stroke%3D%22%23666666%22%20fill%3D%22%23000000%22%3E%3F%3C/text%3E%0A%20%3C/g%3E%0A%3C/svg%3E" alt="Image preview" />
<input type="file" id="file1" style="display:none">
<button id="btn">选择图片</button>
<span id="msgName"></span>
<script>
btn.onclick = function(){
file1.click();
}
file1.onchange = function(){
var file = file1.files[0];
//如果一个文件被选中
if(file){
//一张图片被选中
if (/image/.test(file.type)){
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(){
uploadPreview.src = reader.result;
msgName.innerHTML = file.name;
}
//其他格式文件被选中
} else {
alert("You must select a valid image file!");
}
}
}
</script>
demo如下:
<input type="file" id="file1" style="display:none">
<button id="btn">按钮</button>
<div id="result"></div>
<script>
btn.onclick = function() {
file1.click();
}
file1.onchange = function() {
var reader = new FileReader();
reader.readAsDataURL(file1.files[0]);
reader.onload = function(e){
var img =new Image();
console.log(e.target.result);
img.src = e.target.result;
document.body.appendChild(img);
}
}
</script>
输出 src 如下:
Blob URL
使用Blob URL,也可以用来显示缩略图
<input id="file1" type="file" accept="image/gif,image/jpeg,image/jpg,image/png,image/x-icon" style="display:none">
<button id="btn">选择图片</button>
<div id="fileList"></div>
<script>
btn.onclick = function(){file1.click();}
//保存图片的名称
var dataArr = [];
file1.onchange = function(){
var file = file1.files[0];
//如果一个文件被选中
if(file){
var name = file.name;
var id = name.split('.').join('_');
//检测图片是否已经被存储过
if(dataArr.indexOf(id) > -1){
//将保存过的图片转移到最下方
fileList.appendChild(document.getElementById(id));
}else{
if(/image/.test(file.type)){
dataArr.push(id);
var img = document.createElement('img');
img.onload = function(){
URL.revokeObjectURL(img.src);
}
img.src= URL.createObjectURL(file);
img.height = 60;
var oDiv = document.createElement('div');
oDiv.id = id;
var oSpan = document.createElement('span');
oSpan.innerHTML = name + ":" + file.size + " bytes";
oDiv.appendChild(img);
oDiv.appendChild(oSpan);
fileList.appendChild(oDiv);
}
}
}
}
</script>
demo 如下:
<input type="file" id="file1" style="display:none">
<button id="btn">按钮</button>
<div id="result"></div>
<script>
btn.onclick = function() {
file1.click();
}
file1.onchange = function() {
var src = URL.createObjectURL(file1.files[0]);
console.log(src);
var img = new Image();
img.src = src;
img.width = 100;
img.height = 100;
document.body.appendChild(img);
}
</script>
输出 src 如下:
文件内容
readAsText() 可以以字符串形式读取并显示文件内容
<input id="file1" type="file" style="display:none">
<button id="btn">选择文件</button>
<div id="fileData" style="border:1px solid black;width:300px;overflow:auto"></div>
<script>
btn.onclick = function(){file1.click();}
file1.onchange = function(){
var file = file1.files[0];
//如果一个文件被选中
if(file){
var reader = new FileReader();
reader.readAsText(file);
reader.onload = function(){
fileData.innerHTML = reader.result;
}
}
}
</script>
拖放选择
围绕读取文件信息,结合使用HTML5拖放API和文件API,能够创造出令人瞩目的用户界面:在页面上创建了自定义的放置目标之后,你可以从桌面上把文件拖放到该目标。与拖放一张图片或者一个链接类似,从桌面上把文件拖放到浏览器中也会触发drop事件。而且可以在event.dataTransfer.files中读取到被放置的文件,当然此时它是一个File对象,与通过文件输入字段取得的File对象一样
[注意]IE9-浏览器不支持event.dataTransfer
从电脑上选择一个图片文件,并拖放到网页中指定区域,图片缩略图将显示到网页上
<div id="targetArea" style="height:50px;line-height:50px;width:210px;background:lightblue;">请将图片文件拖放到该区域内</div>
<div id="result"></div>
<script>
function addEvent(target,type,handler){
if(target.addEventListener){
target.addEventListener(type,handler,false);
}else{
target.attachEvent('on'+type,function(event){
return handler.call(target,event);
});
}
}
function preventDefault(e){
e = e || event;
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
}
addEvent(document,'dragover',preventDefault);
addEvent(document,'drop',preventDefault);
addEvent(targetArea,'dragenter',preventDefault);
addEvent(targetArea,'dragover',preventDefault);
addEvent(targetArea,'dragleave',preventDefault);
addEvent(targetArea,'drop',preventDefault);
targetArea.ondragenter = function(e){this.style.outline = "1px solid black";}
targetArea.ondragleave = function(e){this.style.outline = "";}
targetArea.ondrop = function(e){
e = e || event;
this.style.outline = "";
var file = e.dataTransfer.files[0];
if(file){
//一张图片被选中
if (/image/.test(file.type)){
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(){
var oDiv = document.createElement('div');
oDiv.id = file.name.split('.').join('_')
var img = new Image();
img.src = reader.result;
img.height = 60;
var oName = document.createElement('span');
oName.innerHTML = file.name;
var oDel = document.createElement('button');
oDel.innerHTML = '删除';
oDel.onclick = function(){
result.removeChild(oDiv);
}
oDiv.appendChild(img);
oDiv.appendChild(oName);
oDiv.appendChild(oDel);
result.appendChild(oDiv);
}
//其他格式文件被选中
} else {
alert("You must select a valid image file!");
}
}
}
</script>
文件进度
使用onprogress事件的loaded和total属性,可以实现文件进度显示
<input id="file1" type="file" style="display:none">
<button id="btn">选择文件</button>
<div id="fileData"></div>
<script>
btn.onclick = function(){file1.click();}
file1.onchange = function(){
var file = file1.files[0];
//如果一个文件被选中
if(file){
var reader = new FileReader();
reader.readAsText(file);
reader.onprogress = function(e){
e = e || event;
fileData.innerHTML = '文件进度为:' + e.loaded + '/' + e.total;
}
}
}
</script>
文件上传
方法一:使用表单提交实现文件上传
文件上传最基本的方法是使用HTML表单选择本地文件进行上传,在form表单中通过<input type="file">标记选择本地文件。并且,必须在<form>元素中将enctype设置为"multipart/form-data",将method设置为"post"
另外,需要在<form>表单中设置一个hidden类型的input框,其中name值为MAX_FILE_SIZE的隐藏值域,通过设置其value值限制上传文件的大小
<form action="pp.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="1000000">
<input type="file" name="file1">
<button>上传文件</button>
</form>
方法二:使用FormData实现文件上传
创建一个FormData()对象,通过它调用append()方法并传入相应的File对象作为参数。然后,再把FormData对象传递给XHR的send()方法
[注意]IE9-浏览器不支持使用FormData()上传文件
<input type="file" name="file1" id="file1">
<div id="result"></div>
<script>
var oFile = document.getElementById('file1');
oFile.onchange = function(e){
//创建xhr对象
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP');
};
var data = new FormData();
data.append('file',oFile.files[0])
//异步接受响应
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
//实际操作
result.innerHTML = xhr.responseText;
}
}
}
//发送请求
xhr.open('post','pp.php',true);
xhr.send(data);
}
</script>
方法三:使用File API实现文件上传
通过File API传送二进制文件
[注意]IE9-浏览器不支持
<input type="file" name="file1" id="file1">
<div id="result"></div>
<script>
var oFile = document.getElementById('file1');
oFile.onchange = function(e){
//创建xhr对象
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP');
};
var data = oFile.files[0];
//异步接受响应
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
//实际操作
result.innerHTML = xhr.responseText;
}
}
}
//发送请求
xhr.open('post','pp.php',true);
xhr.setRequestHeader("content-type",data.type);
xhr.send(data);
}
</script>
<?php
$file = 'photo/test1.jpg';
touch($file); function binary_to_file($file){
$content = $GLOBALS['HTTP_RAW_POST_DATA']; // 需要php.ini设置
if(empty($content)){
$content = file_get_contents('php://input'); //不需要php.ini设置,内存压力小
}
$ret = file_put_contents($file, $content, true);
return $ret;
};echo '文件上传成功!';
?>
删除文件
最后,提一个小知识点,使用<input type="file>控件选择文件后,如何删除文件呢?一般地,有两种方法。一种是使用form表单的reset()方法,重置表单;另一种是将<input type="file>控件的value值置空,但第二种方法IE10-浏览器不支持
<form id="myForm">
<input type="file" id="myFile">
</form>
<button id="btn1">删除文件方法1</button>
<button id="btn2">删除文件方法2</button>
<script>
var myFile = document.getElementById('myFile');
var myForm = document.getElementById('myForm');
btn1.onclick = function(){
myFile.value = '';
}
btn2.onclick = function(){
myForm.reset();
}
</script>
[转]文件file属性详解的更多相关文章
- 15.python文件(file)方法详解
文件的基本操作 文件读写: 文件的读写满足以下3个步骤: 1).打开文件 2).操作数据(读.写) 3).关闭文件 --> 不要忘记 1).打开文件: python的open() 方法用于打开一 ...
- 【56】java本地文件File类详解
1.java类的介绍 public class File extends Object implements Serializable, Comparable<File> 文件和目录路径名 ...
- hibernate的.hbm.xml文件文件配置属性详解
一般.hbm.xml文件如下面: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "- ...
- Linux文件权限与属性详解 之 SUID、SGID & SBIT
Linux文件权限与属性详解 之 一般权限 Linux文件权限与属性详解 之 ACL Linux文件权限与属性详解 之 SUID.SGID & SBIT Linux文件权限与属性详解 之 ch ...
- Linux文件权限与属性详解 之 一般权限
目录 一般属性 1. iNode: 3152621 2. 文件类型 3.文件访问权限 4. 链接数目: 5. 文件所有者 6. 文件所属组 7. 文件大小 8. 修改时间 9. 文件名称 Linux文 ...
- Linux文件权限与属性详解 之 ACL
Linux文件权限与属性详解 之 一般权限 Linux文件权限与属性详解 之 ACL Linux文件权限与属性详解 之 SUID.SGID & SBIT Linux文件权限与属性详解 之 ch ...
- 轻松学习Linux之Shell文件和目录属性详解
轻松学习Linux之Shell文件和目录属性详解 轻松学习Linux之理解Sitcky 轻松学习Linux之理解umask 轻松学习Linux之理解SUID&SGUID 本系列多媒体教程已完成 ...
- Linux文件权限与属性详解 之 chattr & lsattr
Linux文件权限与属性详解 之 一般权限 Linux文件权限与属性详解 之 ACL Linux文件权限与属性详解 之 SUID.SGID & SBIT Linux文件权限与属性详解 之 ch ...
- Linux文件权限与属性详解 之 su & sudo
Linux文件权限与属性详解 之 一般权限 Linux文件权限与属性详解 之 ACL Linux文件权限与属性详解 之 SUID.SGID & SBIT Linux文件权限与属性详解 之 ch ...
随机推荐
- opencv编译:The CXX compiler identification is unknown The C compiler identification is unknown
opencv编译:The CXX compiler identification is unknown The C compiler identification is unknown 解决方法: F ...
- 深入理解Java虚拟机(类加载机制)
文章首发于微信公众号:BaronTalk 上一篇文章我们介绍了「类文件结构」,这一篇我们来看看虚拟机是如何加载类的. 我们的源代码经过编译器编译成字节码之后,最终都需要加载到虚拟机之后才能运行.虚拟机 ...
- 来杭州云栖大会,全面了解企业如何实现云上IT治理
企业上云的现状与趋势 云计算,如今已经成为了像水和电一般关系到国计民生的国家基础设施.云计算为企业带了前所未有的资源交付效率和运维效率的提升,同时也用全新的技术帮助企业在新的价值网络中创造新的商业赛道 ...
- csps模拟67神炎皇,降雷皇,幻魔皇题解
题面:https://www.cnblogs.com/Juve/articles/11648975.html 神炎皇: 打表找规律?和$\phi$有关? 答案就是$\sum\limits_{i=2}^ ...
- VS2010-MFC(对话框:模态对话框及其弹出过程)
转自:http://www.jizhuomi.com/software/160.html 一.模态对话框和非模态对话框 Windows对话框分为两类:模态对话框和非模态对话框. 模态对话框是这样的对话 ...
- freemarker 嵌套循环 (导出word时,修改ftl模板)
1.循环 (循环输出reportList列表的每行的姓名) <#list reportList as report> ${report.name} </$list> 2.嵌套循 ...
- springmvc-高级参数绑定-映射-异常-json数据交互-拦截器
1.1. 高级参数绑定 1.1.1. 复制工程 把昨天的springmvc-web工程复制一份,作为今天开发的工程 复制工程,如下图: 粘贴并修改工程名为web2,如下图: 工程右键点击,如下图: 修 ...
- 几种远程调用接口协议简单比较和web service(SOAP)与HTTP接口的区别:
什么是web service? 答:soap请求是HTTP POST的一个专用版本,遵循一种特殊的xml消息格式Content-type设置为: text/xml任何数据都可以xml化. ...
- DBUtils(DataSourceUtils提供数据源)
DBUtils是apache组织的一个工具类,jdbc的框架,更方便我们使用 使用步骤: 1.导入jar包(commons-dbutils-1.4.jar,c3p0-0.9.1.2.jar) 1.1导 ...
- [转]一分钟明白 VS manifest 原理
什么是vs 程序的manifest文件 manifest 是VS程序用来标明所依赖的side-by-side组建,如ATL, CRT等的清单. 为什么要有manifest文件 一台pc上,用一组建往往 ...