MDN中的介绍 URL
接口用于解析,构造,规范化和编码 URL。它通过提供允许你轻松阅读和修改 URL 组件的属性来工作。通常,通过在调用 URL 的构造函数时将 URL 指定为字符串或提供相对 URL 和基本 URL 来创建新的 URL 对象。然后,你可以轻松读取 URL 的已解析组成部分或对 URL 进行更改。
静态方法createObjectURL
URL.createObjectURL()
静态方法会创建一个 DOMString
,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document
绑定。这个新的URL 对象表示指定的 File
对象或 Blob
对象。
简单的理解一下就是将一个file或Blob类型的对象转为UTF-16的字符串,并保存在当前操作的document下。
URL.createObjectURL()与FileReader.readAsDataURL()
返回值
- FileReader.readAsDataURL(file)可以得到一段base64的字符串。
- URL.createObjectURL(file)可以得到当前文件的一个内存URL。
内存使用
- FileReader.readAsDataURL(file)的返回值是转换后的超长base64字符串(长度与要解析的文件大小正相关)。
- URL.createObjectURL(file)的返回值虽然是字符串,但是是一个url地址
内存清理
- FileReader.readAsDataURL(file)依照js垃圾回收机制自动从内存中处理
- URL.createObjectURL(file) 存在与当前的document内,清除方式只有unload()事件或 revokeObjectURL()手动清楚
执行机制
- FileRead.readAsDataURL(file)通过回调的形式返回.异步执行
- URL.createObjectURL(file) 直接返回,同步执行
其它
-
FileReader.readAsDataURL(file)当多个文件同时处理时,需要每一个文件对应一个新的FileReader对象。
URL.createObjectURL(file)依次返回无影响。
URL.createObjectURL(file)得到本地内存容器的URL地址,方便预览,多次使用需要注意手动释放内存的问题,性能优秀。
FileReader.readAsDataURL(file)胜在直接转为base64格式,可以直接用于业务,无需二次转换格式。
URL.createObjectURL 应用场景
图片预览
以前我们想要预览图片,只能是上传图片到后端后,获取到url然后赋予给img标签,才能得到回显预览,但是有了URL.createObjectURL就不需要这么麻烦了,直接可以在前端就达到预览的效果~
<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>
音视频流传输
举个例子,我们通过MediaStream 去不断推流,达到了视频显示的效果,有了URL.createObjectURL我们并不需要真的有一个url赋予video标签,去让视频显示出来,只需要使用URL.createObjectURL去构造一个临时的url即可非常方便
<body>
<video id="videoElement" autoplay playsinline></video>
<script>
const videoElement = document.getElementById('videoElement');
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then((stream) => {
videoElement.srcObject = stream;
})
.catch((error) => {
console.error('Error accessing webcam:', error);
});
</script>
</body>
WebWorker
我们知道,想要用 WebWorker 的话,是要先创建一个文件,然后在里面写代码,然后去与这个文件运行的代码进行通信,有了URL.createObjectURL就不需要新建文件了,比如下面这个解决excel耗时过长的场景,可以看到,我们传给WebWorker的不是一个真的文件路径,而是一个临时的路径~
const handleImport = (ev: Event) => {
const file = (ev.target as HTMLInputElement).files![0];
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标签就能下载了,我们也可以用URL.createObjectURL去生成一个临时url
// 创建文件 Blob
const blob = new Blob([/* 文件数据 */], { type: 'application/pdf' });
// 创建下载链接
const downloadUrl = URL.createObjectURL(blob);
const downloadLink = document.createElement('a');
downloadLink.href = downloadUrl;
downloadLink.download = 'document.pdf';
downloadLink.textContent = 'Download PDF';
document.body.appendChild(downloadLink);