在开发中,前端通常会遇到这样一个场景:
后端给的接口返回的图片数据是一串二进制数据,需要将数据转换成dataurl,然后赋值给图片的src的属性,那么该怎么做呢?
<body>
<div id="box"></div>
<script >
let box=document.getElementById('box')
let img=document.createElement('img')
// getCodeImg是axios实例二次封装后的方法
getCodeImg().then(res=>{
// res.data是一串二进制的数据
const blob=new Blob([res.data])
var reader=new window.FileReader()
reader.readAsDataURL(blob)
reader.onload=function(){
// result是解析好的base64图片
img.src=reader.result
}
})
box.appendChild(img)
</script>
</body>
那么如何去理解dataurl和base64图片呢?
传统的图片上传模式
- 首先是用户选择一张图片
- 访问服务器ajax请求过去
- 服务器处理过后,会提供一个可以访问的url地址
- 显示图片的src,显示预览图
缺点
- 用户可能不一定要上传这张图片
- 图片较大会导致用户长时间看不到图片
- 有的时候选择图片之后,会有裁剪的需求,那么先上传再裁剪的方法就会多占用一次网络资源
更好的方法是
- 用户选择了图片之后直接在本地进行处理,跟网络无关
- 用户选择图片之后,生成dataurl,设置img的src显示预览图
dataUrl是什么?
- 本质上是一个固定格式的字符串,这个字符串可以直接替代url,文件或图片数据不用从远程服务器上去拿
格式
data:[<media type>]:[base64],<data>
MiME类型 例如:application/javascript、text/plain等
如果不使用base64,<data>可以使用原始类型的数据
- 图片是典型的二进制数据,就需要用到base64编码方式(将二进制数据转换成可打印字符)
示例
// 不管用
<input type="file"/>
<img src="" id="preview" alt="">
<script>
let inp=document.querySelector('input')
inp.onchange=function(){
console.log(this.files[0]) //因为可以上传多个文件
const inp=document.querySelector('input')
// 对于文件而言,本质就是一个流式数据
// 创建流式读取器
const reader=new FileReader()
reader.onload=function(e){
// 通过事件参数e拿到读取结果
console.log(e.target.result) // 获取到dataURl
// 可以直接给src赋值这个字符串
preview.src=e.target.result
// 如果上传的是一张图片,就可以对图片进行任意的操作,例如 裁剪,调色,整个过程不需要用到网络传输
// 操作完之后上传服务器 。。。。。。。。。。。。。
}
reader.readAsDataURL(this.files[0]) //异步
}
</script>