Skip to main content

URL.createObjectURL 使用场景

URL.createObjectURL 通常用于将 Blob 或 File 对象转换为 URL,因此我们可以很方便的实现直接预览、文件下载等功能。

图片预览

<body>
<input type="file" id="fileInput" />
<img id="preview" src="" alt="Preview" />
<script>
const fileInput = document.getElementById('fileInput')
fileInput.addEventListener('change', event => {
const file = event.target.files[0]
const fileUrl = URL.createObjectURL(file)
const previewElement = document.getElementById('preview')
previewElement.src = fileUrl
})
</script>
</body>

音视频流传输

// 假设有一个视频文件的Blob对象
const videoBlob = new Blob([videoData], { type: 'video/mp4' })

// 创建一个URL
const videoUrl = URL.createObjectURL(videoBlob)

// 将URL赋值给video元素的src属性
const videoElement = document.getElementById('myVideo')
videoElement.src = videoUrl

需要注意的是,当不再需要这个 URL 时,应该调用 URL.revokeObjectURL(url) 来释放内存。这在处理大量数据或长时间运行的应用中尤为重要。

// 当不再需要视频URL时,释放内存
URL.revokeObjectURL(videoUrl)

WebWorker

想要用 WebWorker 的话,是要先创建一个文件,然后在里面写代码,然后去与这个文件运行的代码进行通信。

有了 URL.createObjectURL 就不需要新建文件了,比如下面这个解决 excel 耗时过长的场景,我们传给 WebWorker 的不是一个真的文件路径,而是一个临时的路径:

const handleImport = (ev: Event) => {
const file = (ev.target as HTMLInputElement).files![0];

// new Blob 创建文件内容
// URL.createObjectURL 创建临时的文件路径
// 创建 worker
const worker = new Worker(
URL.createObjectURL(
new Blob([
`
importScripts('https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.4/xlsx.full.min.js');
onmessage = function(e) {
const fileData = e.data;
const workbook = XLSX.read(fileData, { type: 'array' });
const sheetName = workbook.SheetNames[0];
const sheet = workbook.Sheets[sheetName];
const data = XLSX.utils.sheet_to_json(sheet, { header: 1 });
postMessage(data);
};
`,
]),
),
);

// 使用 FileReader 读取文件内容
const reader = new FileReader();
reader.onload = function (e: any) {
// 文件内容
const data = new Uint8Array(e.target.result);
worker.postMessage(data);
};
reader.readAsArrayBuffer(file);

// 监听Web Worker返回的消息
worker.onmessage = function (e) {
console.log('解析完成', e.data);
worker.terminate(); // 当任务完成后,终止Web Worker
};
};

下载文件

下载文件其实就是有一个 url 赋予到 a 标签上,然后点击 a 标签就能下载了。

如果我们获取到了文件内容(一般要转成 Blob 数据),也可以用 URL.createObjectURL 去生成一个临时 url 下载文件:

function download(data: Blob | File, saveName: string): void {
const link = document.createElement('a')
link.href = URL.createObjectURL(data)
link.download = saveName
link.click()
}