在开发的时候,有需要前端预览上传的图片的需求,在完成这个需求后来总结一下

首先我们需要先了解input 和 file类型

Input 标签的file类型,提供了上传文件的功能,通过此类型,可以上传文件到服务器。


input的file类型,在上传文件时,会返回一个File对象,这个对象会存在一个FileList数组里边。之所以存在数组里边,主要是方便实现多文件上传。File对象继承自Blob对象,也就是说Blob对象的属性和方法,File对象也可以使用,而File对象本身也有自己的属性和方法。

下图是浏览器打印出来的FileList : 

各项代表的意思分别是:

* lastModified属性,返回File对象引用文件最后的修改时间。
* lastModifiedDate属性,引用文件最后修改时间的Date对象。
* name属性,所引用文件的名字。
* size属性,返回文件大小。
* webkitRelativePath属性,相关的Path或URL。
* type属性,返回文件的多用途互联网邮件扩展类型(MIME类型)。
* getAsBinary() 将文件内容按照原始二进制形式解析成字符串并返回.
 

前端显示上传图片有两种方法:

上传照片前                                                                上传照片后



 HTML: 
<div id="containner"> <input type="file" id="imgFile"
onchange="previewFile()"><br> <img src="" height="200" alt="Image preview...">
</div>
 JS:

1、通过window.URL.createObjectURL(blob) 

      blob 为Blob对象 或者 File对象

    这个方法会根据传入的参数创建一个指向该参数对象的URL. 这个URL的生命仅存在于它被创建的这个文档里


function previewFile() { var preview = document.querySelector('img') var
fileDom = document.querySelector('input[type=file]') // 获取得到file 对象 var file =
fileDom.files[0] // 限制上传图片的大小 if(file.size > 1024 * 1024 * 2) { alert('图片大小不能超过
2MB!'); return false; } // 创建url var imgUrl = window.URL.createObjectURL(file)
preview.setAttribute("src", imgUrl) // 更改img url 以后释放 url preview.onload =
function() { // console.log('图片加载成功') URL.revokeObjectURL(imgUrl) } }
附注:

在每次调用 createObjectURL() 方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。

所以当不再需要这些 URL 对象时,每个对象必须通过调用 URL.revokeObjectURL()
<https://developer.mozilla.org/zh-CN/docs/Web/API/URL/revokeObjectURL>
 方法来释放。浏览器会在文档退出的时候自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。

 

 

2、通过FileReader.readAsDataURL(blob)

  blob 为Blob对象 或者 File对象

     读取操作完成的时候,readyState 会变成已完成(DONE),并触发 loadend 事件,同时 result
属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容,如图(为截取的一部分):


function previewFile() { var preview = document.querySelector('img'); var
fileDom = document.querySelector('input[type=file]') var file =
fileDom.files[0] // 限制上传图片的大小 if(file.size > 1024 * 1024 * 2) { alert('图片大小不能超过
2MB!'); return false; } // 当前浏览器支持FileReader if(window.FileReader) { var reader
= new FileReader() reader.readAsDataURL(file) reader.addEventListener("load",
function () { console.log('reader.result', reader.result) preview.src =
reader.result }, false) }else { alert('Not supported by your browser!') } }
 

FileReader 

     FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob
对象来指定要读取的文件或数据,即 FileReader.readAsDataURL(blob)  的 参数blob 为 File对象 或 Blob
对象。 同时也适用于window.URL.createObjectURL()

  File对象: 

*           可以是来自用户在一个<input>元素上选择文件后返回的FileList对象         
*           可以是来自拖放操作生成的 DataTransfer对象
*           可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果
 blob对象(二进制数据):

*           通过new Blob()创建的对象就是Blob对象(关于Blob对象 ,下一篇再写)
*           XMLHttpRequest里,如果指定responseType为blob,那么得到的返回值也是一个blob对象.
 上面这两种方式,都可以让图片在前端页面显示,但是如果需要将图片的数据发送给服务器,FileReader.readAsDataURL
这种方式更好,可以将得到的数据作为data传递给服务器。

3、如果拿到图片的地址,可以通过获取图片的blob对象,然后再通过FileReader.readAsDataURL(blob)拿到图片data

    第一步 :(r如果图片不是存在本地电脑的)可以发送ajax请求去获取url 的blob(base64 的图片)值
function getImageBlob(url){ const xhr = new XMLHttpRequest() xhr.open("get",
url, true) // 设置responseType 的类型, 为arraybuffer、blob都可以 xhr.responseType =
"blob" return new Promise((resolve, reject) => { xhr.onload = () => {
resolve(xhr.response) //data:URL格式的字符串(base64编码)以表示所读取文件的内容。 } xhr.onerror = ()
=> reject() xhr.send() }) }
第二步: 获取图片数据
function getImageData(imgBlob) { // imgBlob 是一个ArrayBuffer类型的对象或者Blob对象 return
new Promise((resolve, reject) => { const reader = new FileReader()
reader.onloadend = () => resolve(reader.result) reader.onerror = reject //
设置转换的URL的类型,通过Blob 构造函数的type 来设置读取出来的数据的类型 reader.readAsDataURL(new
Blob([imgBlob], { type: "image/jpeg" })) }); }
第三步: 封装
function urlToData(url) { return getImageData(url).then((imageData) =>
getTypeOfImage(imageData) ) }
最后通过 await urlToData(url) 就可以得到图片的数据了