前端预览input上传的图片

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

首先我们需要先了解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() 将文件内容按照原始二进制形式解析成字符串并返回.

 

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

上传照片前                                                                上传照片后

前端预览input上传的图片_第1张图片前端预览input上传的图片_第2张图片

 HTML: 


Image preview...

 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() 方法来释放。浏览器会在文档退出的时候自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。

 

 

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对象: 

  •           可以是来自用户在一个元素上选择文件后返回的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) 就可以得到图片的数据了

你可能感兴趣的:(js)