在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. hue install

    http://ju.outofmemory.cn/entry/105162 Hue是一个开源的Apache Hadoop UI系统,最早是由Cloudera Desktop演化而来,由Cloudera ...

  2. Java编程中的美好

    java程序员如何写出"优美"代码,动力节点告诉你怎么办: 1.注释尽可能全面 对于方法的注释应该包含详细的入参和结果说明,有异常抛出的情况也要详细叙述:类的注释应该包含类的功能说 ...

  3. Trie tree实践

    1.Trie树 Trie树即字典树或前缀树, 2.实践 代码实践如下: package cn.edu.buaa.trie; import java.util.HashSet; /** * @autho ...

  4. 通过ipv6访问 g o o g l e

    Google.Youtube.Facebook等均支持IPv6访问,IPv4网络的用户大部分都无法访问,比如Gmail,Google Docs等等各种相关服务.而该类网站大部分均已接入IPv6网络,因 ...

  5. <head>中<meta name="viewport" content="width=device-width,initical-scale=1"的作用>

    <meta name="viewport" content="width=device-width,initical-scale=1"的作用> co ...

  6. 深入理解javascript原型和闭包(6)——继承

    为何用“继承”为标题,而不用“原型链”? 原型链如果解释清楚了很容易理解,不会与常用的java/C#产生混淆.而“继承”确实常用面向对象语言中最基本的概念,但是java中的继承与javascript中 ...

  7. NOIP2009 Hankson的趣味题

    题目描述 Description Hanks 博士是BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫Hankson.现在,刚刚放学回家的Hankson 正在思考一个有趣的问题.今天在 ...

  8. PHP定时备份MySQL,mysqldump语法大全

    几个常用操作: 1.备份 # 只导出表结构 d:/PHP/xampp/mysql/bin/mysqldump -h127.0.0.1 -P3306 -uroot -p123456 snsgou_sns ...

  9. 用JS获取地址栏参数的方法

    采用正则表达式获取地址栏参数: function GetQueryString(name) {      var reg = new RegExp("(^|&)"+ nam ...

  10. redis部署

    下载软件 [root@localhost /]# wget http://download.redis.io/releases/redis-2.8.9.tar.gz 解压.编译.安装 [root@lo ...