JavaScript 文件对象详解

在浏览器中操作文件,多数情况下用到的是 File 对象,从 <input type='file' /> 元素获取,进而继续操作(例如将选择的图片展示在页面上,用ajax将文件上传至服务器等)。这里介绍在浏览器中操作文件的相关API.

File 对象继承自 Blob 对象,先看看 Blob 对象。

1. Blob 对象

Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。

Blob构造函数 Blob(array[, options])

  • array 是一个由ArrayBuffer, ArrayBufferView, Blob, string 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。string会被编码为UTF-8。
  • options 是一个可选的对象,它可能会指定如下两个属性:
    • type,默认值为 "",它代表了将会被放入到blob中的数组内容的MIME类型
    • endings,默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入。 它是以下两个值中的一个: "native",代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 "transparent",代表会保持blob中保存的结束符不变。

示例:

var content1 = ['This is my firt trip to an island'];
var blob1 = new Blob(content, {type: 'text/plain'});
var content2 = {name: 'Alice', age: 23};
var blob2 = new Blob([JSON.stringify(content2, null, 2)], {type: 'application/json'});
复制代码

Blob实例属性

属性名称读/写描述
size只读 Blob 对象中所包含数据的大小(字节)。
type只读一个字符串,表明该Blob对象所包含数据的MIME类型。如果类型未知,则该值为空字符串。例如 "image/png".

示例:

var content = ['<div id="box"><p class="pra">a paragraph</p></div>'];
var blob = new Blob(content, {type: 'text/html'});
console.log(blob.size); // 50
console.log(blob.type); // text/html
复制代码

Blob实例方法

  • slice([start[, end[, contentType]]])

slice 方法接收三个可选参数,startend 都是数值,表示截取的范围,contentType 指定截取的内容的 MIME 类型。返回一个新的 Blob对象。

var blob = new Blob(['This is an example of Blob slice method'], {type: 'text/plain'});
console.log(blob.size); // 39
var newBlob = blob.slice(10, 20, 'text/plain');
console.log(newBlob.size); // 10
复制代码

Blob 对象中读取内容可以使用 FileReader. 下文会介绍。

2. File 对象

File构造函数

我们接触的多数关于 File 的操作都是读取,js也为我们提供了手动创建 File 对象的构造函数:File(bits, name[, options])

  • bits (required) ArrayBuffer,ArrayBufferView,Blob,或者 Array[string] — 或者任何这些对象的组合。这是 UTF-8 编码的文件内容。。

  • name [String] (required) 文件名称,或者文件路径.

  • options [Object] (optional) 选项对象,包含文件的可选属性。可用的选项如下:

    • type: string, 表示将要放到文件中的内容的MIME类型。默认值为 '' 。
    • lastModified: 数值,表示文件最后修改时间的 Unix 时间戳(毫秒)。默认值为 Date.now()。

示例:

var file1 = new File(['text1', 'text2'], 'test.txt', {type: 'text/plain'});

根据已有的 blob 对象创建 File 对象:

var file2 = new File([blob], 'test.png', {type: 'image/png'});

File实例属性

File 对象的实例内容不可见,但是有以下属性可以访问:

属性名称读/写描述
name只读返回文件的名称.由于安全原因,返回的值并不包含文件路径 。
type只读返回 File 对象所表示文件的媒体类型(MIME)。例如 PNG 图像是 "image/png".
lastModified只读number, 返回所引用文件最后修改日期,自 1970年1月1日0:00 以来的毫秒数。
lastModifiedDate只读Date, 返回当前文件的最后修改日期,如果无法获取到文件的最后修改日期,则使用当前日期来替代。

示例:

<input type="file" id='file'>

document.getElementById('file').addEventListener('change', function(event){
  const file = this.files[0];
  if (file) {
    console.log(file.name);
    console.log(file.size);
    console.log(file.lastModified);
    console.log(file.lastModifiedDate);
  }
});

备注: 基于当前的实现,浏览器不会实际读取文件的字节流,来判断它的媒体类型。它基于文件扩展来假设;将PNG 图像文件的后缀名重命名为 .txt,那么读取的该文件的 type 属性值为 "text/plain", 而不是 "image/png" 。而且,file.type 仅仅对常见文件类型可靠。例如图像、文档、音频和视频。不常见的文件扩展名会返回空字符串。开发者最好不要依靠这个属性,作为唯一的验证方案。

File实例方法

  • slice([start[, end[, contentType]]])

File 对象没有定义额外的方法,由于继承了 Blob 对象,也就继承了 slice方法,用法同上文 Blobslice 方法。

FileReader, URL.createObjectURL(), createImageBitmap(), 及 XMLHttpRequest.send() 都能处理 Blob 和 File。

3. FileReader 对象

FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 FileBlob 对象指定要读取的文件或数据。

其中 File 对象可以是来自用户在一个 <input> 元素上选择文件后返回的 FileList, 也可以来自拖放操作生成的 DataTransfer 对象,还可以是来自在一个 HTMLCanvasElement 上执行 mozGetAsFile() 方法后返回结果。

FileReader构造函数

var reader = new FileReader()

构造函数不需要传入参数,返回一个 FileReader 的实例。FileReader 继承 EventTarget对象。

FileReader实例属性

属性名称读/写描述
error只读 DOMException 的实例,表示在读取文件时发生的错误 。
result只读文件的内容,该属性仅在读取操作完成后(load)后才有效,格式取决于读取方法
readyState只读表示读取文件时状态的数字

备注: readeyState的取值如下:

常量名描述
0EMPTY还没有加载任何数据
1LOADING数据正在被加载
2DONE已完成全部的读取请求.

使用示例:

var reader = new FileReader();
console.log(reader.error);       // null
console.log(reader.result);      // null
console.log(reader.readyState);  // 0
console.log(reader.EMPTY);       // 0
console.log(reader.LOADING);     // 1
console.log(reader.DONE);        // 2

EMPTYLOADINGDONE 这三个属性同时存在于 FileReader 和它的的原型对象上,因此实例上有这三个属性,FileReader 对象本身也有这三个属性:

console.log(FileReader.EMPTY);   // 0
console.log(FileReader.LOADING); // 1
console.log(FileReader.DONE);    // 2

FileReader事件

文件的读取是一个异步的过程,和 XMLHttpRequest 对象一样,在读取操作过程中会触发一系列事件。

事件名称描述使用示例
abort读取操作被中断时触发。reader.onabort = function(event) {}
error在读取操作发生错误时触发。reader.onerror = function(event) {}
load读取操作完成时触发。reader.addEventListener('load', function(event) {})
loadstart读取操作开始时触发。reader.onloadstart = function(event) {}
loadend读取操作结束时(要么成功,要么失败)触发。reader.onloadend = function(event) {}
progress在读取Blob时触发。reader.onprogress = function(event) {}

FileReader实例方法

FileReader 的实例具有以下可操作的方法:

方法名称描述使用示例
abort()手动终止读取操作,只有当 readyState 为 1 时才能调用,调用后,readyState 值为 2reader.abort()
readAsArrayBuffer(blob)读取指定的 BlobFile 对象。读取操作完成后(触发loadend事件),result属性将包含一个 ArrayBuffer 对象表示所读取的文件的数据。reader.readAsArrayBuffer(blob)
readAsDataURL(blob)读取指定的 BlobFile 对象。读取操作完成后(触发loadend事件),result属性将包含一个 data:URL 格式的字符串(base64编码)reader.readAsArrayBuffer(file)
readAsBinaryString(blob)已废弃,用 readAsArrayBuffer 代替--
readAsText(blob[, encoding])将 Blob 或者 File 对象转根据特殊的编码格式转化为内容(字符串形式), 默认编码是 utf-8 reader.readAsArrayBuffer(blob)

读取本地图片示例:

<input type="file" id='file' accept="image/png, image/jpg, image/jpeg, image/gif" />><br />>
<img src="" alt="Image preview...">

var preview = document.querySelector('img');
var reader  = new FileReader();
reader.addEventListener("load", function () {
  preview.src = reader.result;
}, false);
document.getElementById('file').addEventListener('change', function (event) {
  var file = this.files[0];
  if (file) {
    reader.readAsDataURL(file);
  }
});

读取多个文件示例 - CodePen

dataURL是base64编码的数据格式,展示类型为字符串,形如: data:image/jpeg;base64,/9j/4QXERXhpZgAATU...

dataURL 转为 blob对象:

function dataURLToBlob (dataurl) {
  let arr = dataurl.split(',');
  let mime = arr[0].match(/:(.*?);/)[1];
  let bstr = atob(arr[1]);
  let n = bstr.length;
  let u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
}

结合上例,根据已有的 <img> 对象创建一个 File 对象:

reader.addEventListener("load", function () {
  preview.src = reader.result;
  var blob = dataURLToBlob(reader.result);
  var newFile = new File([blob], 'test.jpeg', {type: blob.type});
  console.log(newFile.name); // test.jpeg
  console.log(newFile.type);
  console.log(newFile.size);
}, false);

URL.createObjectURL

将图片文件转换成 data:URL 格式供 <img> 元素展示,除了使用 fileReader.readAsDataURL外,还可以使用 URL.createObjectURL方法。 URL.createObjectURL(blob) 方法返回一个 blob: 开头的字符串,指向文件在内存中的地址。

<input type="file" id='file' accept="image/png, image/jpg, image/jpeg, image/gif" /><br />
<img src="" alt="Image preview...">

var preview = document.querySelector('img');
document.getElementById('file').addEventListener('change', function (event) {
  var file = this.files[0];
  if (file) {
    preview.src = URL.createObjectURL(file);
  }
});

综合实例

综合以上,可以实现一个简单的粘贴图片并显示的功能。HTML5提供的内容编辑功能,可以粘贴部分图片,例如从网页上复制的图片。但是使用截图工具截取的图片无法粘贴显示,而且从网页上复制的图片会带有原来的样式,其图片url也是原来图片的指向。我们使用以下代码可以统一这两种粘贴操作,实现统一的效果。

<div id="comment" contenteditable></div>

#comment{
  border: 1px solid #ccc;
  min-height: 500px;
  padding: 10px;
}
#comment:focus {
  border-color: #ccc;
  outline: none;
}
.img-paste {
  max-width: 100%;
}

var comment = document.getElementById('comment');
comment.addEventListener('paste', function(event) {
  console.log(event);
  var item = event.clipboardData.files[0];
  if (item && /image/.test(item.type)) {
    var img = new Image();
    img.src = URL.createObjectURL(item);
    img.className = 'img-paste';
    this.appendChild(img);
    event.preventDefault();
  }
}, false);

实例效果可以查看这里

参考链接



原文发布时间为:2018年06月29日

原文作者:Mr-dang

本文来源: 掘金  如需转载请联系原作者
  • 8
    点赞
  • 0
    评论
  • 16
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
第1章 JavaScript简介 1 1.1 JavaScript是什么 1 1.2 JavaScript不是什么 2 1.3 JavaScript的用处 3 1.4 JavaScript及其在Web页面中的位置 3 1.5 Ajax是什么 5 1.6 JavaScript是什么样子的 6 1.7 JavaScript及其在Web开发中承担的角色 7 1.8 JavaScript和事件 9 1.9 标准化JavaScript和W3C 11 1.9.1 JavaScript对象 12 1.9.2 文档对象模型 12 1.10 关于浏览器 13 1.10.1 JavaScript的版本 14 1.10.2 你的浏览器遵循标准吗 16 1.10.3 浏览器是否已启用JavaScript 16 1.11 JavaScript代码放在哪儿 17 1.12 验证标签 20 1.12.1 W3C验证工具 21 1.12.2 Validome验证工具 21 1.13 应知应会 22 练习 23 第2章 脚本的安装 24 2.1 HTML文档与JavaScript 24 2.2 语法细节 27 2.2.1 区分大小写问题 27 2.2.2 自由形式及保留字 27 2.2.3 语句及分号 28 2.2.4 注释 28 ... 2.2.5 〈script〉标签    2.3 生成HTML 并输出显示    2.3.1 字符串及字符串串联    2.3.2 write()及writeln()方法    2.4 关于调试    2.5 调试工具    2.5.1 Firefox    2.5.2 在Internet Explorer 8中调试    2.5.3 [removed]URL 协议    2.6 JavaScript与旧浏览器或受限的浏览器    2.7 应知应会    练习    第3章 数据类型、字面量和变量    3.1 数据类型    3.1.1 基本数据类型    3.1.2 复合数据类型    3.2 变量    3.2.1 有效变量名    3.2.2 声明和初始化变量    3.2.3 动态或宽松类型语言    3.2.4 变量作用域    3.2.5 变量的拼接    3.3 常量    3.4 要注意的bug    3.5 应知应会    练习    第4章 对话框    4.1 与用户交互    4.1.1 alert()方法    4.1.2 prompt()方法    4.1.3 confirm()方法    4.2 应知应会    练习    第5章 运算符    5.1 JavaScript运算符和表达式    5.1.1 赋值运算符    5.1.2 优先级和结合性    5.2 运算符类型    5.2.1 算术运算符    5.2.2 快捷赋值运算符    5.2.3 递增运算符和递减运算符    5.2.4 拼接运算符    5.2.5 比较运算符    5.2.6 逻辑运算符    5.2.7 条件运算符    5.2.8 位运算符    5.3 数字、字符串还是布尔值?数据类型转换    5.3.1 parseInt()函数    5.3.2 parseFloat()函数    5.3.3 eval()函数    5.4 特殊运算符    5.5 应知应会    练习    第6章 条件选择    6.1 控制结构、块及复合语句    6.2 条件    6.2.1 if/else    6.2.2 if/else if    6.2.3 switch    6.3 循环    6.3.1 while循环    6.3.2 do/while循环    6.3.3 for循环    6.3.4 for/in循环    6.3.5 使用break和continue控制循环    6.3.6 嵌套循环及标签    6.4 应知应会    练习    第7章 函数    7.1 什么是函数    7.1.1 函数声明和调用    7.1.2 返回值    7.1.3 匿名函数变量    7.1.4 闭包    7.1.5 递归    7.1.6 函数是对象    7.2 调试技巧    7.2.1 函数语法    7.2.2 使用try/catch和throw捕捉异常    7.3 应知应会    练习    第8章 对象    8.1 什么是对象    8.1.1 对象及点语法    8.1.2 使用构造函数创建对象    8.1.3 对象的属性    8.1.4 对象的方法    8.2 类和用户自定义函数    8.2.1 什么是类    8.2.2 什么是this   
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值