图片,base64,formData,Blob
背景
图片上传是一个非常common的功能,当上传的时候难免需要跟后端人员协商传过去的参数是什么类型或者什么格式,这里就涉及到三个概念:
formData
base64
二进制流
作为一个从建筑电气转行过来的半路出家的前端开发人员(I am completely confused!),这三个概念在上传图片的时候分别表示什么意思?本地图片如何转化格式并提交给后端呢?
formData
formData
就是将form
表单元素的name
和value
进行组合,实现表单数据的序列化,从而减少表单元素的拼接,提高工作效率。
Web API 提供了FormData
方法,提供了一种表示表单数据的键值对的构造方式,通过FormData.append(key, value)
向FormData
中添加新的属性值。
一般有两种使用方法
创建空对象
let fd = new FormData()
fd.append('name', 'Jane') // append方法添加数据
fd.append('age', 18)
API.saveFormApi(fd).then(res => {}) // 假设saveFormApi是一个接口请求方法
(够直观了吧!!!)
使用已有表单初始化对象
// html
<form id="formId" action="" method="post">
<input type="text" name="name">名字
<input type="text" name="age">年纪
<input type="submit" value="提交">
</form>
// js
var formEle = document.getElementById("formId")
var fd= new FormData(formEle)
// 我们可以根据key来访问表单中的字段
var name = fd.get("name") // 获取名字
var age = fd.get("age") // 获取年纪
// 也可以在此基础上,添加其他数据
fd.append("sex","female")
// 这里请求就不写了,fd可以作为参数发送请求了
base64
base64
是一种基于64个可打印字符来表示二进制数据的表达方法,它常用于处理文本数据的场合,表示、传输、存储一些二进制数据。
图片的base64
编码就是将一张图片编码成一串字符串,使用该字符串可以代替图片地址,直接在浏览器打开是可以访问该图片的。有什么好处呢?
- 提升性能
网页上每一个图片都是需要消耗http请求下载的,图片的下载始终需要向服务器发出请求,base64
可以随着html
下载到本地,可以减少http请求次数 - 加密
使用base64
转化的图片用户是一眼看不出图片内容的,只能看到编码内容 - 方便引用
可以将图片转为base64
格式文件,定义个全局样式,在需要使用的地方可以直接加类名,不需要多层找文件路径,提升效率。
那么问题来了,下面我们我们如何将图片转成base64
呢
canvas转图片
canvas.toDataURL()
可以将canvas
画布内容直接转化成base64
内容
具体可以参考echarts导出图片
Blob对象转base64
Blob
表示二进制类型的大对象,通常是影像、声音或多媒体文件,在JS中Blob
类型的对象表示不可变的类似文件对象的原始数据。
// html
<input type="file" id="imagefile" />
// js
let file = document.getElementById("imagefile").files[0]
let reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function () {
console.log(reader.result)
}
创建一个FileReader
对象并为该对象绑定onload
相应的事件处理函数,然后调用FileReader
对象的readAsDataURL()
方法,把本地图片对应的File
对象转化为Data URL
。
对于FileReader
对象来说,除了支持把Blob/File
对象转换成Data URL
之外,它还提供了readAsArrayBuffer()
和readAsText()
方法,用于把Blob/File
对象转换为其他数据格式。
base64转Blob对象
将图片base64
转成Blob
大对象二进制流并作为formData
格式发送请求
// 假装这里是一张canvas画布
let canvasEle = xxx
let mime = 'image/png'
let base64Result = canvasEle.toDataURL(mime)
let bytes = atob(base64Result.split(',')[1])
// 方法一
let ab = new ArrayBuffer(bytes.length)
let ia = new Uint8Array(ab)
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i)
}
let blob = new Blob([ab], {type: 'image/png'})
let fd = new FormData()
fd.append('picture', blob)
fd.append('name', 'Jane')
fd.append('age', 18)
// 方法二
let array = []
for (let i = 0; i < bytes.length; i++) {
array.push(bytes.charCodeAt(i))
}
let blob = new Blob([new Uint8Array(array)], {type: 'image/jpeg'})
let fd = new FormData()
fd.append('picture', blob)
fd.append('name', 'Jane')
fd.append('age', 18)
// 发送请求
API.SceneSave(fd).then(res => {})
点击view source