搞懂前端二进制系列(二):🍈File、FileReader与Base64

参考资料:

一、File 类型

​ Web 应用程序的一个主要的痛点是无法操作用户计算机上的文件。2000 年之前,处理文件的唯一方

式是把<input type="file">放到一个表单里,仅此而已。File API 与 Blob API 是为了让 Web 开发者

能以安全的方式访问客户端机器上的文件,从而更好地与这些文件交互而设计的

​ File API 仍然以表单中的文件输入字段为基础,但是增加了直接访问文件信息的能力,每个 File 对象都有一些

只读属性:

属性 说明
name 本地系统中的文件名
size 以字节计的文件大小
type 包含文件 MIME 类型的字符串
lastModifiedDate 表示文件最后修改时间的字符串。这个属性只有 Chome 实现了
构造方法
const file = new File(array, name[, options])
  • array 是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成,DOMStrings会被编码为UTF-8
  • name 表示文件名称,或者文件路径
  • options 是一个可选,它可能会指定如下两个属性:
    • type,默认值为 "",内容的MIME类型
    • lastModified: 数值,表示文件最后修改时间的 Unix 时间戳(毫秒)。默认值为 Date.now()

常见的MIME类型,请参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

成员方法:

由于Blob是File的超集,因此,下面的方法几乎和blob一样

方法 说明
slice() Blob 中截取一部分并返回一个新的 Blob(用法同数组的 slice)
arrayBuffer() 返回一个以二进制形式展现的 promise
stream() 返回一个ReadableStream对象
text() 返回一个文本形式的 promise
// 转成stream
console.log(file1.stream());

// 转成Arraybuffer
file1.arrayBuffer().then((res) => {
  console.log(res);
});

// 转成文本
file1.text().then((res) => {
  console.log(res);
});

二、FileReader

​ FileReader类型表示一种异步文件读取机制。可以把FileReader 想象成类似于XMLHttpRequest,

只不过是用于从文件系统读取文件,而不是从服务器读取数据。

属性
属性 说明
error 表示在读取文件时发生的错误
result 返回文件的内容。只有在读取操作完成后,此属性才有效,返回的数据的格式取决于是使用哪种读取方法来执行读取操作的。
readyState 表示FileReader状态的数字。0 还没有加载任何数据。1 数据正在被加载。2 已完成全部的读取请求
方法

需要注意的是 ,无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result属性中

方法名 说明
abort() 中止读取操作。在返回时,readyState 属性为 DONE。
readAsArrayBuffer() 将读取的内容转成ArrayBuffer
readAsBinaryString() 将读取的内容转成二进制数据
readAsDataURL() 将读取的内容转成并将其编码为 base64 的 data url。 格式是 data:[<mediatype>][;base64],<data>
readAsText() 将数据读取为给定编码(默认为 utf-8 编码)的文本字符串
事件
事件名 说明
onabort 处理 abort 事件。该事件在读取操作被中断时触发
onerror 处理 error 事件。该事件在读取操作发生错误时触发
onload 处理 load 事件。该事件在读取操作完成时触发
onloadstart 处理 loadstart 事件。该事件在读取操作开始时触发
onloadend 处理 loadend 事件。该事件在读取操作结束时(要么成功,要么失败)触发
onprogress 处理 progress 事件。该事件在读取Blob时触发
例子
 <input type="file" id="files-list" multiple>
  <div id="output"></div>
  <div id="progress"></div>
  <script>
    window.onload = function() {
      let filesList = document.getElementById("files-list");
      filesList.addEventListener("change", (event) => {
        let info = "",
          output = document.getElementById("output"),
          progress = document.getElementById("progress"),
          files = event.target.files,
          type = "default",
          reader = new FileReader();
        if ( /image/.test(files[0].type) ) {
          reader.readAsDataURL(files[0]);
          type = "image";
        } else {
          reader.readAsText(files[0]);
          type = "text";
        }
        reader.onerror = function () {
          output.innerHTML = "Could not read file, error code is " +
            reader.error.code;
        };

        reader.onprogress = function (event) {
          if ( event.lengthComputable ) {
            progress.innerHTML = `${ event.loaded }/${ event.total }`;
          }
        };
        reader.onload = function () {
          let html = "";
          switch (type) {
            case "image":
              html = `<img src="${ reader.result }">`;
              break;
            case "text":
              html = reader.result;
              break;
          }
          output.innerHTML = html;
        };
      });
    }
  </script>

​ 以上代码从表单字段中读取一个文件,并将其内容显示在了网页上。如果文件的 MIME 类型表示它

是一个图片,那么就将其读取后保存为数据 URI,在 load 事件触发时将数据 URI 作为图片插入页面中。

如果文件不是图片,则读取后将其保存为文本并原样输出到网页上。progress 事件用于跟踪和显示读

取文件的进度,而 error 事件用于监控错误。

​ 如果想提前结束文件读取,则可以在过程中调用 abort()方法,从而触发 abort 事件。在 load、

error 和 abort 事件触发后,还会触发 loadend 事件。loadend 事件表示在上述 3 种情况下,所有读

取操作都已经结束。

三、Base64

​ Base64是一种编码格式,在前端经常会碰到,格式是 data:[<mediatype>][;base64],<data>

除了使用工具进行Base64编码外,js还内置了两个方法能进行字符串的Base64的编码和解码。

​ Base64目的不是为了加密解密,二是为了能完整无差错的传输数据

优点:
  • 可以将二进制数据(比如图片)转化为可打印字符,方便传输数据
  • 对数据进行简单的加密,肉眼是安全的
  • 如果是在html或者css处理图片,可以减少http请求
缺点:
  • 内容编码后体积变大, 至少1/3
    因为是三字节变成四个字节,当只有一个字节的时候,也至少会变成三个字节
  • 编码和解码需要额外工作量
例子

除了使用工具进行Base64编码外,js还内置了两个方法能进行字符串的Base64的编码和解码

const str1 = "hello randy";

// 编码
const b1 = window.btoa(str1);
console.log(b1); // aGVsbG8gcmFuZHk=

// 解码
const str2 = window.atob(b1);
console.log(str2); // hello randy

不过需要值得注意的是,这两个自带的方法不能加密中文

posted @   SuanYunyan  阅读(284)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示