浏览器文件、流知识大合集(持续补充)

168 阅读4分钟

本文章旨在整理浏览器流、二进制数据操作相关,涉及ArrayBuffer、Blob、File、FileReader、Base64、Hash、进制转换、编解码相关,可当作工具,同时,也可以当作coding时的快速查阅文档。

🔧 工具:


Blob

定义:不可修改的类文件对象,是File对象的父类

  • 来源:
    • constructor(array, options)
      • array元素类型:ArrayBuffer、TypedArray、DataView、Blob、strings(tring将使用utf-8来编码)
      • options:
        • type: Mime Type
        • endings
    • File对象(用户文件系统)
const array = ['<q id="a"><span id="b">hey!</span></q>']; // an array consisting of a single string
const blob = new Blob(array, { type: "text/html" }); // the blob
  • 返回对象
    • 实例属性:
      • size:bytes大小
      • type:对应constructor中的Mime Type
    • 实例方法:
      • 返回指定类型的数据:
        • arrayBuffer()
        • stream()
        • text() utf-8编码
      • 剪切
        • slice(start, end)

ArrayBuffer

定义:用来代表固定长度的二进制数据流,概念上等同于Node中的Buffer对象

  • 特点:不能直接操作该对象,仅可以通过代表特定格式buffer的TypedArray、DataView对象来进行读写
  • 来源:
    • constructor(byteLength)

    • Base64 string

    • 本地文件:File对象和Blob对象

TypedArray

基于二进制数据buffer的类数组视图,相当于是字符串和二进制数据的关系。

  • 特点:
    • 无法new实例化,会报错 // TypeError: Abstract class TypedArray not directly constructable
    • 是Int8Array、Uint8Array这样数组的父类,相当于abstract class
    • 不能被冻结,因为底层arraybuffer能够被其他类型数组操作
    • 访问不了原型链属性以及越界元素
  • 具体的视图类(subclass):
    • Int8Array
    • Uint8Array
    • 等等
  • 来源:
    • Contructor
      • TypedArray:会对不同类型的TypedArray进行转换,同时非大数TypedArray只能传递给非大数TypedArray
      • arrayLike object
      • length 默认contructor参数为0
      • buffer,byteOffeset,length:三个参数都是必填的
  • 实例属性:
    • @@toStringTag
    • buffer
    • byteLength 字节长度
    • byteOffset
    • length 元素个数
  • 实例方法:
    • at
    • copyWithin
    • entries / keys / values
    • every
    • fill
    • filter
    • find
    • forEach
    • includes
  • 常用方法:
    • TypedArray.from(arrayLike) 相当于Array.from,此处对应的是父类
const uint16 = Int16Array.from('12345');

console.log(uint16);
// expected output: Int16Array [1, 2, 3, 4, 5]
    • TypedArray.of 相当于Array.of

FileReader

定义:访问File、Blob以及数据流(buffer)的类

  • 特点:
    • File对象包括(并非能访问文件系统,如果浏览器端要访问,可以使用Ajax):
      • 通过input标签选择的文件对象FileList
      • drag、drop操作产生的DataTransfer对象
  • Contructor:FileReader
  • 实例属性:
    • readyState
Tag描述
EMPTY0没有加载数据
LOADING1正在加载数据
DONE2完成加载
    • result:返回加载的内容,根据readAs等API来决定内容为什么。
  • 实例方法:
    • readAsArrayBuffer
    • readAsBinaryString
    • readAsDataURL
    • readAsText
  • 事件
    • abort

    • load 加载完成事件

    • progress

FormData

定义:用来构建key/value集合,可以被用于fetch()/XMLHttpRequest.send()方法,http请求Content-Type常常为“multipart/form”,常用于文件传输,也可以被传递给URLSearchParams,生成query。

  • 来源
    • constructor
    • form元素预填充数据到FormData,name属性作为FormData的key值,使用实例如下:
<form id="form">
  <input type="text" name="text1" value="foo" />
  <input type="text" name="text2" value="bar" />
  <input type="text" name="text2" value="baz" />
  <input type="checkbox" name="check" checked disabled />
</form>

// script
const form = document.getElementById('form');
const formData = new FormData(form);
  • 实例方法:
    • append/set
    • delete
    • entries/keys/values
    • get/getAll
    • has

URLSearchParams

定义:用来处理生成URL query string的工具方法

  • 来源:
    • constructor
      • string 对待application/x-www-form-urlencoded一样处理
      • key/value对,比如FormData

Hash算法

定义:对任意输入数据进行计算,得到一个固定长度的输出摘要。常见的Hash算法有:md5、SHA-1

参考链接:

www.liaoxuefeng.com/wiki/125259…

常见处理流/文件的方法:

  • URL.createObjectURL
  • URL.revokeObjectURL
  • ****base64 ****字符串:
      • atob
      • btoa

Q&A:

  • URL.createObjectURL生成的blob协议是什么?
  • 前端如何下载文件?以及如何处理预览/直接下载问题
function downloadFile(url, fileName = 'fileName') {
      const el = document.createElement('a');
      el.style.display = 'none';
      el.setAttribute('target', '_blank');
      /**
       * 1. download的属性是HTML5新增的属性
       * 2. href属性的地址必须是非跨域的地址,如果引用的是第三方的网站或者说是前后端分离的项目(调用后台的接口),这时download就会不起作用。
       * 3. 如果是下载浏览器无法解析的文件,例如.exe,.xlsx..那么浏览器会自动下载,但是如果使用浏览器可以解析的文件,比如.txt,.png,.pdf....浏览器就会采取预览模式
       * 所以,对于.txt,.png,.pdf等的预览功能我们就可以直接不设置download属性(前提是后端响应头的Content-Type: application/octet-stream,如果为application/pdf浏览器则会判断文件为 pdf ,自动执行预览的策略)
       */
      fileName && el.setAttribute('download', fileName);
      el.href = url;
      console.log(el);
      document.body.appendChild(el);
      el.click();
      document.body.removeChild(el);
    };
  • String.prototype.length返回的是什么
    • javascript采用utf-16编码,返回的不是字节数,而是utf-16单元数;
  • encodeURLComponent/decodeURLComponent
    • 编码原理:
      • 找到字符的Unicode码点,转换成utf-8编码,并将utf-8编码的每一个字节转换成16进制拼接上“%”即可

Todo:

  • structuredClone() 是什么方法
  • 实战一下大文件上传下载前后端
  • axios库url query为什么不对'['']'进行编码?