如何优雅的处理前端开发中的File

简介: 如何优雅的处理前端开发中的File

640.jpg写在前面


在前端开发中,我们经常会遇到对文件的操作,特别是对图片的操作。在Node端,提供了file相关的接口,供我们使用。在浏览器中,Html5提供了File相关的Web Api。

本文将小小总结一下如何使用File相关的api来操作文件以及相关的一些知识。


File对象


一个File对象包含了以下的属性:


lastModified: 只读。文件最后修改时间(UNIX时间戳)。name: 只读。文件名(不包含完整路径)。size: 只读。文件大小。type: 只读。MIME TYPE。


看一个例子:

640.png


在浏览器中,我们也可以直接使用File构造函数来构造一个文件对象实例。


var json = `{ "a": 1 }`;var f = new File([json], 'test.json', {    type: 'application/json'});console.log(f);


640.png


一个File对象的内容可以是很多数据类型,包括:ArrayBuffer、ArrayBufferView、Blob、DOMString(在JS中,DOMString就是String)。本文不做进一步详细介绍。


如何获取一个File对象


那么,如何获取一个文件对象呢?上面提到了,我们可以直接使用File构造函数。大多数的情况下,我们是需要让用户进行选择,这个时候,就需要用到 input 标签了。代码也很简单,我们只需要把input标签的 type 设置为 file 就行。


<html>    <input type='file'/>    <script>        const el = document.querySelector('input');        el.addEventListener('change', e=> {            const fileList = e.target.files;            [].slice.call(fileList).forEach(file => {                console.log(file);            });        });</script></html>

我们只需要监听input标签的change事件,就可以拿到文件对象了。这里需要注意的时候,我们拿到的其实是一个文件列表,而这个文件列表是一个类数组对象,需要转换为数组,才能完全像数组一样遍历。

640.png



如果想选择多个文件,则需要在input标签上增加 multiple 属性。如果只接受某些类型的文件,可以添加 accept 属性。


<!-- 可以多选文件 --><input type='file' multiple />
<!-- 多选,只能选择图片文件 --><input type='file' multiple accept='image/*'/>


上面的图中我们可以看到,直接使用input标签是不太美观的。我们可以将input标签隐藏,使用代码触发input标签的点击事件,就可以达到效果。


<html>    <input type='file' style="display:none"/>    <button>这是一个帅气的按钮</button>    <script>        const inputEl = document.querySelector('input');        inputEl.addEventListener('change', e => {            const fileList = e.target.files;            [].slice.call(fileList).forEach(file => {                console.log(file);            });        });           const btnEl = document.querySelector('button');        btnEl.addEventListener('click', () => {            inputEl.click();        });</script></html>


如何读取File对象的内容

上面讲了如何拿到一个文件对象,那么怎么读取文件的内容呢?这个时候,就需要用到另外一个Web Api了:FileReader


使用FileReader读取文件内容,主要步骤为:


// 1、声明一个FileReader对象实例var fileReader = new FileReader();
// 2、监听读取完成事件fileReader.onload = function(e) {  const result = e.target.result;}
// 3、读取文件内容// 这里的 file 为文件对象。fileReader.readAsDataURL(file); // 以base64的方式读取
// fileReader.readAsArrayBuffer() 以ArrayBuffer的方式读取// fileReader.readAsText() 以字符串的方式读取


一个很常见的场景:读取本地图片,并展示缩略图。实现起来十分简单。


<html>    <input type='file' accept='image/*' />    <script>        const el = document.querySelector('input');        el.addEventListener('change', e=> {            const imgFile = e.target.files[0];            const reader = new FileReader();            reader.onload = function(e) {              const base64 = e.target.result;              const imgEl = new Image();              imgEl.src = base64;              imgEl.onload = function() {                document.body.appendChild(imgEl);              }            }            reader.readAsDataURL(imgFile);        });</script></html>


640.png


想要在浏览器中预览文件,还有另外一种方法:使用 window.URL.createObjectURL


<html>    <input type='file' accept='image/*' />    <script>        const el = document.querySelector('input');        el.addEventListener('change', e=> {            const imgFile = e.target.files[0];            const imgSrc = window.URL.createObjectURL(imgFile);            console.log(imgSrc);            const imgEl = new Image();            imgEl.src = imgSrc;            imgEl.onload = function() {                document.body.appendChild(imgEl);                window.URL.revokeObjectURL(imgFile);            }        });</script></html>


640.png


可以看到,这里图片的src,是一个以  blob:开头 的字符串。这是浏览器自己实现的一个协议,表示对一个资源的引用,需要挂载到网页中的资源对象上(比如img,video),才能展示出来。


如何从页面上下载一个自定义的File


下面的场景是比较常见的:在页面上生成一个自定义文件,然后下载下来。要实现这个需求,可以按照下面的思路:


  1. 首先生成一个文件。这个在前文有讲到,我们可以直接使用 new File 来构造一个文件即可。
  2. 生成一个对该文件的引用。可以使用 window.URL.createObjectURL 来创建对文件的引用。
  3. 下载。使用 a 标签,设置download属性。


代码示例:


<html>    <button>点击下载</button>    <script>        const btnEl = document.querySelector('button');        btnEl.addEventListener('click', function() {            const json = `{ "a": 1 }`;            const file = new File([json], 'test.json', {                type: 'application/json'            });            const url = window.URL.createObjectURL(file);            const aTag = document.createElement('a');            aTag.href = url;            aTag.download = 'test.json';            aTag.click();        });</script></html>


640.png


写在后面


本文主要介绍了在前端页面中,如何处理File。其实File对象是继承自Blob对象,File是特殊的Blob。Blob 是 Binary Large Object 的缩写,表示一个不可变、原始数据的类文件对象,主要用于处理二进制的数据。关于这一部分的内容,可以移步本次推送的第二篇文章。


另外,最新版的Chrome已经支持直接读写本地文件了。


Chrome浏览器支持直接读写本地文件了

相关文章
|
前端开发 JavaScript 数据格式
图片URL转file文件(前端+后端node.js)
图片URL转file文件(前端+后端node.js)
|
移动开发 前端开发 Android开发
前端html input =“file“ ios/安卓解决无法选择图库/拍照问题
前端html input =“file“ ios/安卓解决无法选择图库/拍照问题
2021 0
|
4月前
|
存储 前端开发 JavaScript
前端base64转file文件方法
前端base64转file文件方法
550 0
|
4月前
|
JSON 前端开发 JavaScript
JS前端读取本地上传的File文件对象内容(包括Base64、text、JSON、Blob、ArrayBuffer等类型文件)
JS前端读取本地上传的File文件对象内容(包括Base64、text、JSON、Blob、ArrayBuffer等类型文件)
|
前端开发 JavaScript 数据安全/隐私保护
前端通过Blob或File文件获取二进制数据
前端通过Blob或File文件获取二进制数据
前端通过Blob或File文件获取二进制数据
|
存储 监控 前端开发
【前端知乎系列】File FileList 和 FileReader 对象详解
【前端知乎系列】File FileList 和 FileReader 对象详解
334 0
|
Web App开发 前端开发 测试技术
前端常见兼容问题系列6: 一些安卓APP的WebView中<input type="file">不工作
安卓APP的WebView默认屏蔽了该控件的使用,有些安卓APP之所以能支持文件选择和上传,主要可能是有可能采取了如下措施之一: (1)可能在该APP中重写了相关方法 (2)提供了JS Bridge来供web页面调用
10097 2
|
Web App开发 前端开发 JavaScript
前端开发:css技巧,如何设置select、radio 、 checkbox 、file这些不可直接设置的样式 。
前言:   都说程序员有三宝:人傻,钱多,死得早。博主身边的程序“猿”一大半应了这三宝,这从侧面说明了一个问题,只有理性是过不好日子的。朋友们应该把工作与生活分开,让生活变得感性,让工作变得理性,两者相提并行,岂不快哉。
1110 0
|
30天前
|
存储 前端开发 JavaScript
前端语言串讲 | 青训营笔记
前端语言串讲 | 青训营笔记
20 0
|
3月前
|
JSON 前端开发 JavaScript
前端Ajax、Axios和Fetch的用法和区别笔记
前端Ajax、Axios和Fetch的用法和区别笔记
62 2