在HTML表单中,可以上传文件的唯一控件就是<input type="file">

注意:当一个表单包含<input type="file">时,表单的enctype必须指定为multipart/form-datamethod必须指定为post,浏览器才能正确编码并以multipart/form-data格式发送表单的数据。

出于安全考虑,浏览器只允许用户点击<input type="file">来选择本地文件,用JavaScript对<input type="file">value赋值是没有任何效果的。当用户选择了上传某个文件后,JavaScript也无法获得该文件的真实路径:

待上传文件:

通常,上传的文件都由后台服务器处理,JavaScript可以在提交表单时对文件扩展名做检查,以便防止用户上传无效格式的文件:

var f = document.getElementById('test-file-upload');
var filename = f.value; // 'C:\fakepath\test.png'
if (!filename || !(filename.endsWith('.jpg') || filename.endsWith('.png') || filename.endsWith('.gif'))) {
alert('Can only upload image file.');
return false;
}

File API

由于JavaScript对用户上传的文件操作非常有限,尤其是无法读取文件内容,使得很多需要操作文件的网页不得不用Flash这样的第三方插件来实现。

随着HTML5的普及,新增的File API允许JavaScript读取文件内容,获得更多的文件信息。

HTML5的File API提供了FileFileReader两个主要对象,可以获得文件信息并读取文件。

下面的例子演示了如何读取用户选取的图片文件,并在一个<div>中预览图像:

图片预览:

 

文件: 山脉.jpg
大小: 660122
修改: Tue Nov 17 2015 11:04:14 GMT+0800 (中国标准时间)

var
fileInput = document.getElementById('test-image-file'),
info = document.getElementById('test-file-info'),
preview = document.getElementById('test-image-preview');
// 监听change事件:
fileInput.addEventListener('change', function () {
// 清除背景图片:
preview.style.backgroundImage = '';
// 检查文件是否选择:
if (!fileInput.value) {
info.innerHTML = '没有选择文件';
return;
}
// 获取File引用:
var file = fileInput.files[0];
// 获取File信息:
info.innerHTML = '文件: ' + file.name + '<br>' +
'大小: ' + file.size + '<br>' +
'修改: ' + file.lastModifiedDate;
if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {
alert('不是有效的图片文件!');
return;
}
// 读取文件:
var reader = new FileReader();
reader.onload = function(e) {
var
data = e.target.result; // 'data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...'
preview.style.backgroundImage = 'url(' + data + ')';
};
// 以DataURL的形式读取文件:
reader.readAsDataURL(file);
});

上面的代码演示了如何通过HTML5的File API读取文件内容。以DataURL的形式读取到的文件是一个字符串,类似于data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...,常用于设置图像。如果需要服务器端处理,把字符串base64,后面的字符发送给服务器并用Base64解码就可以得到原始文件的二进制内容。

回调

上面的代码还演示了JavaScript的一个重要的特性就是单线程执行模式。在JavaScript中,浏览器的JavaScript执行引擎在执行JavaScript代码时,总是以单线程模式执行,也就是说,任何时候,JavaScript代码都不可能同时有多于1个线程在执行。

你可能会问,单线程模式执行的JavaScript,如何处理多任务?

在JavaScript中,执行多任务实际上都是异步调用,比如上面的代码:

reader.readAsDataURL(file);

就会发起一个异步操作来读取文件内容。因为是异步操作,所以我们在JavaScript代码中就不知道什么时候操作结束,因此需要先设置一个回调函数:

reader.onload = function(e) {
// 当文件读取完成后,自动调用此函数:
};

当文件读取完成后,JavaScript引擎将自动调用我们设置的回调函数。执行回调函数时,文件已经读取完毕,所以我们可以在回调函数内部安全地获得文件内容。

廖雪峰js教程笔记14 file文件操作的更多相关文章

  1. 廖雪峰js教程笔记3

    JavaScript的函数在查找变量时从自身函数定义开始,从"内"向"外"查找.如果内部函数定义了与外部函数重名的变量,则内部函数的变量将"屏蔽&qu ...

  2. 廖雪峰js教程笔记13 插入DOM

    当我们获得了某个DOM节点,想在这个DOM节点内插入新的DOM,应该如何做? 如果这个DOM节点是空的,例如,<div></div>,那么,直接使用innerHTML = '& ...

  3. 廖雪峰js教程笔记12 用DOM更新 innerHMTL 和修改css样式

    拿到一个DOM节点后,我们可以对它进行更新. 可以直接修改节点的文本,方法有两种: 一种是修改innerHTML属性,这个方式非常强大,不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段 ...

  4. 廖雪峰js教程笔记11 操作DOM(包含作业)

    由于HTML文档被浏览器解析后就是一棵DOM树,要改变HTML的结构,就需要通过JavaScript来操作DOM. 始终记住DOM是一个树形结构.操作一个DOM节点实际上就是这么几个操作: 更新:更新 ...

  5. 廖雪峰js教程笔记10 浏览器对象

    JavaScript可以获取浏览器提供的很多对象,并进行操作. window window对象不但充当全局作用域,而且表示浏览器窗口. window对象有innerWidth和innerHeight属 ...

  6. 廖雪峰js教程笔记9 json

    JSON是JavaScript Object Notation的缩写,它是一种数据交换格式. 在JSON出现之前,大家一直用XML来传递数据.因为XML是一种纯文本格式,所以它适合在网络上交换数据.X ...

  7. 廖雪峰js教程笔记6 generator一个坑 看完python在回来填坑

    generator(生成器)是ES6标准引入的新的数据类型.一个generator看上去像一个函数,但可以返回多次. ES6定义generator标准的哥们借鉴了Python的generator的概念 ...

  8. 廖雪峰js教程笔记5 Arrow Function(箭头函数)

    为什么叫Arrow Function?因为它的定义用的就是一个箭头: x => x * x 上面的箭头函数相当于: function (x) { return x * x; } 箭头函数 阅读: ...

  9. 廖雪峰js教程笔记8 date对象介绍和处理

    在JavaScript中,Date对象用来表示日期和时间. 要获取系统当前时间,用: var now = new Date(); now; // Wed Jun 24 2015 19:49:22 GM ...

随机推荐

  1. 向shell脚本中传入参数

    写一个 程序名为    test.sh    可带参数为 start 和 stop 执行  test.sh start执行  start 内容的代码 执行 test.sh stop 执行 stop 内 ...

  2. openerp7 时区问题

    由于目前openerp 的时区,读取的是UTC 时间,而我国本地时间比UTC 快8小时,这个问题就导致:写入数据库的时候时间相差8小时,以及Openerp日志输出时间格式也相差8小时和 前端显示时间的 ...

  3. BZOJ3172: [Tjoi2013]单词

    传送门 做了这么多题怎么还是无法很好的理解AC自动机呢..果然是个制杖 首先题意表述不是很清晰,这些所有的单词组成了那个文章,所以果断建个AC自动机,建的时候给每个点附加一个权值,建树是经过一次权值即 ...

  4. C#环境

  5. jquery numberbox赋值

    numberbox不能使用$('#id').val( '');只能使用$('#id').numberbox('setValue','');

  6. UIScrollView的缩放原理

    当用户在UIScrollView身上使用捏合手势时,UIScrollView会给代理发送一条消息,询问代理究竟要缩放自己内部的哪一个子控件(哪一块内容) 当用户在UIScrollView身上使用捏合手 ...

  7. XML Schema and XMLspy notes

    Introduction An xml documents consists of elements, attributes and text. There are two structures in ...

  8. MySQL 拷贝数据库表方式备份,还原后提示 table xxx '' doesn`t exist

    MySQL很强大,支持直接拷贝数据库文件快速备份,那数据库文件在哪里呢? 打开MySQL的配置文件 my.ini,找到 datadir 节点,如 datadir="D:/Program Fi ...

  9. Yslow-23条规则

    1. 减少HTTP请求次数 合并图片.CSS.JS,减少首次访问用户等待时间. 2. 使用CDN就近缓存==>智能路由==>负载均衡==>WSA全站动态加速 3. 避免空的src和h ...

  10. PYTHON 深拷贝,浅拷贝

    声明:本篇笔记,模仿与其它博客中的内容 浅拷贝 浅拷贝,在内存中只额外创建第一层数据 import copy n1 = {"k1": "wu", "k ...