总字数 1.1k
预计阅读时间 4 分钟
对于前端的文件上传 , 有很多时候不能直接通过表单提交来完成
包括但不限于下列情况
- 需要对文件(图片)进行压缩, 或者进行修改(比如裁剪)
- 多文件上传 (当然也有办法间接借助表单做到, 但是不够优雅)
- 画布(比如canvas)的快照图片上传
这种情况下就需要将文件内容转化为base64编码, 在JS当中处理后完成上传
获取base64编码
file类型的input
1 | //这是一个<input id='upload-file' type='file' />元素 |
这里获取到的fileBase64
就是文件的base64编码
如果这个文件是一个图片 , 我们当然可以借助它来实现所选图片的预览
( 当然需要判断所选的文件是不是图片 )
比如
1 | //这是一个DIV |
canvas画布
对于canvas画布 , 我们可以借助toDataURL
这个API , 来获得这个画布的快照
1 | var imageBase64 = document.getElementById("test-canvas").toDataURL('image/jpeg', 0.8); |
toDataURL有两个参数, 都是可选的
- 图片格式,默认为 image/png
- 在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量
如果超出取值范围,将会使用默认值 0.92
如果画布没有填充底色, 生成jpeg格式的快照图片, 底色将为黑色
如果需要底色透明, 可以使用 image/png 格式
文件上传
通过观察toDataURL方法的返回结果
可以发现这个字符串的逗号之前是对文件类型的标识
之后才是文件的实际内容(base64编码可以直接表示二进制的内容)
所以在实际执行上传的时候 , 需要使用的是逗号之后的内容
1 | var imgBase64 = document.getElementById("test-canvas").toDataURL('image/png') |
最后的ajax请求是借助axios
来实现的 , 其他的库基本同理 , 遵循各自API即可
后端写法与blob对应的字段名对应即可
比如上面示例代码当中使用的是 uploadImg
那么后端代码大致如下
1 |
|
多文件上传
有了上面的实现方式 , 多文件上传就十分简单了
其实就是对于多个Blob对象 , 执行多次formData.append
注意 : 不是在一个Blob当中添加多个Uint8Array
假如当前页面有多个canvas , 我需要一次性上传这些快照图片
1 | var canvasDoms = document.getElementsByTagName('canvas') |
在后端需要用MultipartFile
对象的数组进行接收
1 |
|