使用URL.createObjectURL()与FileReader API实现文件(图片)上传立即回显
来自mozilla的定义:
FileReader
对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File
或 Blob
对象指定要读取的文件或数据。
其中File对象可以是来自用户在一个<input>
元素上选择文件后返回的FileList
对象,也可以来自拖放操作生成的 DataTransfer
对象,还可以是来自在一个HTMLCanvasElement
上执行mozGetAsFile()
方法后返回结果。
重要提示: FileReader仅用于以安全的方式从用户(远程)系统读取文件内容 它不能用于从文件系统中按路径名简单地读取文件。 要在JavaScript中按路径名读取文件,应使用标准Ajax解决方案进行服务器端文件读取,如果读取跨域,则使用CORS权限。
Note: 此特性在 Web Worker 中可用。
URL.createObjectURL()
静态方法会创建一个 DOMString
,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document
绑定。这个新的URL 对象表示指定的 File
对象或 Blob
对象。
Note: 此特性在 Web Worker 中可用。
注意:此特性在 Service Worker 中不可用,因为它有可能导致内存泄漏。
https://developer.mozilla.org/zh-CN/docs/Web/API/URL/createObjectURL
对比
createObjectURL | FileReader | |
兼容性 | ie10 | ie10 |
执行机制 | 同步执行 | 异步执行(宏任务 - 回调方式) |
返回值 | 获取当前文件的一个内存URL | 获取一段data:base64的字符串 |
内存使用 | createObjectURL返回一段带hash的url,并且一直存储在内存中,直到document触发了unload事件(例如:document close)或者执行revokeObjectURL来释放。 | FileReader.readAsDataURL返回文件的base64字符串,比blob url消耗更多内存,但是在不用的时候会自动从内存中清除(通过垃圾回收机制) |
使用场景 | 使用createObjectURL可以节省性能并更快速,只不过需要在不使用的情况下手动释放内存 | 如果不太在意设备性能问题,并想获取图片的base64,则推荐使用FileReader.readAsDataURL |
用法:
<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)"> <a href="#" id="fileSelect">Select some files</a> <div id="fileList"> <p>No files selected!</p> </div>
1、使用URL对象来展示图片
window.URL = window.URL || window.webkitURL; const fileSelect = document.getElementById("fileSelect"), fileElem = document.getElementById("fileElem"), fileList = document.getElementById("fileList"); fileSelect.addEventListener("click", function (e) { if (fileElem) { fileElem.click(); } e.preventDefault(); // prevent navigation to "#" }, false); function handleFiles(files) { if (!files.length) { fileList.innerHTML = "<p>No files selected!</p>"; } else { fileList.innerHTML = ""; const list = document.createElement("ul"); fileList.appendChild(list); for (let i = 0; i < files.length; i++) { const li = document.createElement("li"); list.appendChild(li); const img = document.createElement("img"); img.src = window.URL.createObjectURL(files[i]); // 生成的地址可以看做是本地的一个静态资源地址 blob:https://mdn.mozillademos.org/7de34695-285e-4d1a-aeaf-7fe363ff42e5 img.height = 60; img.onload = function() { window.URL.revokeObjectURL(this.src); // 生成的图片地址是一个object URL,即使之前创建了同一张图片的object URL,此时也会重新创建,所以为了优化性能,图片加载完成后,请手动释放该对象 } li.appendChild(img); const info = document.createElement("span"); info.innerHTML = files[i].name + ": " + files[i].size + " bytes"; li.appendChild(info); } } }
2、使用来FileReader
展示图片
function handleFiles(files) { for (let i = 0; i < files.length; i++) { const file = files[i]; if (!file.type.startsWith('image/')){ continue } const img = document.createElement("img"); img.classList.add("obj"); img.file = file; preview.appendChild(img); // Assuming that "preview" is the div output where the content will be displayed. const reader = new FileReader(); reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img); reader.readAsDataURL(file); } }
上述两种方式都可以用来预览图片等其他本地资源,具体可自行尝试。