浅谈JS处理文件数据的API:Blob、FileReader、Base64、File?( 三 )


一般情况下 , 在以下情况下 Object URL 会被自动释放:

  • 当相关的 JavaScript 代码执行完成并不再引用 Object URL 时 (垃圾回收释放) 。
  • 当页面被卸载(关闭或导航到其他页面)时 。
  • 当使用 URL.revokeObjectURL() 手动释放 Object URL 时 。
注意:在不需要使用URL时 , 应该通过 URL.revokeObjectURL() 函数来释放它 , 以避免内存泄漏 。如下:
// 创建一个包含图片数据的 Blob 对象const imageData = https://www.isolves.com/it/cxkf/yy/js/2023-08-03/new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10, /* ... */]);const blob = new Blob([imageData], { type: 'image/png' });// 创建 Object URL 并将图片显示在 标签中const imageUrl = URL.createObjectURL(blob);const imageElement = document.getElementById('image');imageElement.src = imageUrl;// 在不需要 Object URL 时释放它// 通常在不需要显示图片或其他二进制数据时调用// 这样可以释放浏览器内存 , 避免内存泄漏// 注意:在实际应用中 , 请根据需要选择合适的时机来调用 URL.revokeObjectURL()// imageElement.onload = () => {//URL.revokeObjectURL(imageUrl);// }; 
Base64Base64 是一种编码方式 , 它将二进制数据转换成只包含 ASCII 字符的文本表示形式 。这种编码方式通常用于在文本协议中传输二进制数据 , 例如在电子邮件、URL、XML、JSON 等文本格式中嵌入图片、音频、视频等二进制数据 。Base64 编码基于 64 个可打印的 ASCII 字符(A-Z , a-z , 0-9 , + 和 /) , 以及一个用于填充的字符(通常是等号 =) 。编码规则如下:
  • 将 3 字节的二进制数据(24 位)划分为四组 , 每组 6 位 。
  • 将每组 6 位二进制数据转换为一个可打印字符 。
  • 如果原始数据不是 3 字节的倍数 , 则会在末尾添加一个或两个等号(=)字符进行填充 。
理论上说:Base64 编码后的数据大小通常会比原始数据大约 33% , 因为每 3 字节的数据会编码成 4 个字符 。会比blob url消耗更多内存 , 但是在不用的时候会自动从内存中清除(通过垃圾回收机制) 。
在 JavaScript 中 , 可以使用 readAsDataURL api 和 canvas 的 toDataURL api 获取 base64 格式的数据流 。
注意:上述方式获取的是一种根据数据类型生成的base64编码数据 , 不是真实一一对应的base64编码规则 , 因为添加了一些数据类型头部 , 即:base64编码的数据和 dataUrl 类型的数据不是一个东西 。如 。`data:image/jpeg;base64,/9j/`,这种的类型 (data: - Data URL 的协议头部、image/jpeg - MIME 类型 , 表示数据的媒体类型、base64 - 表示数据是使用 Base64 编码的 。它告诉浏览器如何解码数据、/9j/ - Base64 编码后的数据的起始部分标识) 。
想获取完整标准的 Base64编码 , 可以使用 btoa() 函数将字符串进行 Base64 编码 , 以及使用 atob() 函数将 Base64 编码的字符串解码为原始字符串 。在 Node.js 中 , 可以使用 Buffer.from() 和 Buffer.toString() 来进行 Base64 编码和解码 。
  • atob(ascii to binary): 解码  , 用于将ascii码解析成binary数据 。用于解码Base64编码的字符串 。
  • btoa(binary to ascii):编码 , 用于将binary数据用ascii码表示 。常用于编码字符串 。(不支持Unicode字符编码) , 它的编码范围实际上是在 0 到 255 的整数值之间 , 即一个字节(8 位)的范围 。
const originalString = 'Hello, world!';const encodedString = btoa(originalString);const decodedString = atob(encodedString);console.log(encodedString); // "SGVsbG8sIHdvcmxkIQ=="console.log(decodedString); // "Hello, world!"想要支持其他的Unicode字符编码 , 可以使用以下方式:
  • 编码时 , 先用encodeURIComponent对字符串进行编码 , 再使用btoa进行编码
  • 解码时 , 先用atob对数据进行解码  , 再用decodeURIComponent对字符串进行解码
let str_unicode = "中国"let encode_str_unicode =btoa(encodeURIComponent(str_unicode));console.log(encode_str_unicode);//JUU0JUI4JUFEJUU1JTlCJUJElet decode_str_unicode = decodeURIComponent(atob(encode_str_unicode));console.log(decode_str_unicode);//中国注意: 上述的decodeURIComponent和encodeURIComponent是一种URI 编码 , 一种将特殊字符转换为可安全传输和显示的形式的编码方式 。在 URI(Uniform Resource Identifier)中 , 某些字符被保留用于特殊用途 , 例如作为分隔符或标记符号 。如果要在 URI 中包含这些保留字符 , 就需要将它们转换为编码形式 , 这样才能正确传输和解析 。比如我们常见到网页路径包含这种参数 `%E4%B8%AD%E5%9B%BD`


推荐阅读