前言作为前端工程师的我们,每天都免不了要和图片打交道。在各大电商平台工作的前端工程师可能感觉更明显。以下是我之前在处理图片时踩过的坑,分享一下我的经验。1.场景复现使用postman请求接口时,在chrome的网络上查看时,返回的图片(二进制)就是这张图片(二进制),也返回这张图片(二进制)。但是调试打印的时候,返回的图片明显是乱码,数据类型发生了变化。想想看,唯一可以更改数据类型的地方是axios。我去翻了一下axios的文档,里面是这样描述的//`responseType`表示服务器响应的数据类型//optionsare'arraybuffer','blob','document','json','text','stream'responseType:'json',//default所以出现乱码的原因是因为:axios默认返回的是json文本形式,强制将二进制图片数据转为json文本形式。一旦找到原因,解决办法就好办了。我们在axios中,默认的responseType返回数据类型是json,改成返回数据类型blob。exportfunctionminiprogramQrcode(params){returnaxios.post(env.MI_URL+'/XXXX/XXX/XXXX',params,//将responseType默认的json改为blob{responseType:'blob',emulateJSON:true})。then(res=>{if(res.data){returnPromise.resolve(res.data)}else{throwres}}).catch(err=>{returnPromise.reject(err)})}next问题就是,如何处理blob对象并显示在前端页面?代码如下:createMiniQrcode(blob){letimg=document.createElement('img')img.onload=function(e){//元素的onload事件触发后,URL对象会被销毁,内存将会被释放。window.URL.revokeObjectURL(img.src)}//浏览器允许URL.createObjectURL()方法为Blob对象生成临时URL。//这个URL以blob://开头,表示它对应一个Blob对象。img.src=window.URL.createObjectURL(blob)document.querySelector('.imgQrCode').appendChild(img)}你以为这就结束了吗?不,不,不。知道如何解决问题是不够的,你需要跳出框框思考。2、发散思路一般来说,后台存储图片有两种方式:一:可以将图片作为独立的文件存储在服务器的指定文件夹中,然后在数据库字段中存储路径;另一种是:将图片转为二进制流,直接存入数据库的Image类型字段。对于第一种存储方式,我们前端可以直接将存储路径赋值给src属性,方便显示。对于第二种存储方式,我们的前端需要将二进制流交给blob对象进行处理,然后通过blobAPI生成一个临时的URL赋值给src属性进行展示。两种存储方式都有对应的解决方案,貌似完美解决了图片显示的问题。但是,我们的业务场景是多样多变的。有时候我们也会遇到这样的场景,比如拖拽图片上传插件后,Blob对象自动返回给你,但是不幸的是,你发现你使用了第三方服务接口只能接收base64格式的数据,是不是有点欲哭无泪?那么图片、url、base64、blob这三种表现形式是否可以进行改造以满足需求呢?1.url转base64url转base64的方法封装//原理:使用canvas.toDataURL转base64urlToBase64(url)的API{returnnewPromise((resolve,reject)=>{letimage=newImage();image.onload=function(){letcanvas=document.createElement('canvas');canvas.width=this.naturalWidth;canvas.height=this.naturalHeight;//将图像插入画布并开始绘制canvas.getContext('2d').drawImage(image,0,0);//resultletresult=canvas.toDataURL('image/png')resolve(result);};//CORS策略,会有跨域问题https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerrorimage.setAttribute("crossOrigin",'Anonymous');image.src=url;//图像加载失败的错误处理image.onerror=()=>{reject(newError('Imagestreamexception'));};}你可以这样调用:letimgUrL=`http://XXX.jpg`this.getDataUri(imgUrL).then(res=>{//转换成base64的图片地址console.log('base64',res)})2.base64转blob方法封装base64转blob//原理:使用URL.createObjectURL来blob对象创建一个临时的URLbase64ToBlob({b64data='',contentType='',sliceSize=512}={}){returnnewPromise((resolve,reject)=>{//使用atob()方法解码数据letbyteCharacters=atob(b64data);letbyteArrays=[];for(letoffset=0;offset
