JavaScript 文件处理: URL.createObjectURL vs. reader.readAsDataURL 全面解析

286 阅读3分钟

JavaScript 文件处理: URL.createObjectURL vs. reader.readAsDataURL 全面解析

在 Web 开发中,处理文件上传、预览和数据传输是常见需求。JavaScript 提供了多种 API 来操作文件,其中 URL.createObjectURL(file)reader.readAsDataURL(file) 都是常用的方法,用于生成可访问文件内容的 URL。 然而,它们在实现方式、性能表现、适用场景和潜在问题上存在显著区别。

一、 用法详解

1. URL.createObjectURL(file)

URL.createObjectURL(file) 方法接收一个 File 对象作为参数,并返回一个表示该文件对象的临时 URL 字符串。 该方法执行速度快,因为它不会读取文件内容,而只是创建一个指向内存中文件对象的引用。

const fileInput = document.getElementById('fileInput');

fileInput.addEventListener('change', (event) => {
  const file = event.target.files[0];
  const objectURL = URL.createObjectURL(file); 

  const image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
});

2. reader.readAsDataURL(file)

reader.readAsDataURL(file) 方法使用 FileReader 对象异步读取文件内容,并将其转换为 Base64 编码的 Data URL 字符串。

const fileInput = document.getElementById('fileInput');

fileInput.addEventListener('change', (event) => {
  const file = event.target.files[0];
  const reader = new FileReader();

  reader.onload = (e) => {
    const image = document.createElement('img');
    image.src = e.target.result; // e.target.result 包含 Data URL 字符串
    document.body.appendChild(image);
  };

  reader.readAsDataURL(file);
});

二、 区别剖析

特性URL.createObjectURLreader.readAsDataURL
返回值文件对象的临时 URL 字符串Base64 编码的 Data URL 字符串
执行方式同步异步,需要监听 FileReader 对象的 load 事件
数据读取不读取文件内容,只创建指向内存中文件对象的引用读取完整的文件内容,并将其转换为 Base64 编码
内存管理创建的 URL 对象会持续占用内存,直到调用 URL.revokeObjectURL() 释放或页面卸载Data URL 字符串存储在内存中,直到 JavaScript 垃圾回收机制将其回收
适用场景快速预览文件内容、处理大文件、需要创建多个文件 URL需要持久化存储文件数据、传输文件数据、需要对文件数据进行进一步处理
兼容性部分旧版浏览器不支持兼容性较好

三、 性能比较

URL.createObjectURL 的执行速度比 reader.readAsDataURL 快得多,因为它不需要读取和转换文件内容。 因此,在需要快速预览文件内容或处理大型文件时,URL.createObjectURL 是更优的选择。

四、 场景选择

  1. 快速预览: 当需要在页面上快速显示图片、音频或视频预览时,URL.createObjectURL 是最佳选择。
  2. 大文件处理: 对于大型文件,使用 reader.readAsDataURL 读取和转换数据会消耗大量时间和内存,而 createObjectURL 更加轻量高效。
  3. 数据存储和传输: 如果需要将文件数据存储到数据库或发送到服务器,则必须使用 reader.readAsDataURL 将其转换为可存储和传输的字符串格式。
  4. 文件操作: 如果需要对文件数据进行进一步处理,例如图像压缩、裁剪等,也需要使用 reader.readAsDataURL 获取完整的图像数据。

五、 内存泄漏风险

URL.createObjectURL 创建的 URL 对象会一直占用内存,直到调用 URL.revokeObjectURL() 方法将其释放,或者当前文档被卸载 (例如关闭页面)。 因此,为了避免内存泄漏,务必在使用完毕后及时调用 URL.revokeObjectURL() 方法释放资源:

const objectURL = URL.createObjectURL(file);

// ... 使用 objectURL ...

URL.revokeObjectURL(objectURL); // 释放资源

六、 总结

URL.createObjectURLreader.readAsDataURL 都是处理文件对象的有效方法,但在性能、适用场景和内存管理方面存在差异。 开发者需要根据具体需求选择合适的方法,并在使用 URL.createObjectURL 时注意及时释放资源,避免内存泄漏。