背景
vue2.x项目,vantUI框架,实现上传图片和视频到后端服务器。
实现
-
支持移动端调起手机摄像头现拍以及选择系统中的文件上传
van-uploader组件API:
注意:当没有设置capture时,会调用系统默认行为,让你选择相机还是文件。当你设置该属性时候,就不会有选择界面!!!如果不喜欢这个系统自带界面可以自己封装一个选择界面,但是,我试了,发现不简单,主要是van-uploader提供的回调函数不够全面,需要自己封装。
-
将base64转为二进制文件流
van-uploade默认是返回的base64格式文件,不管是图片还是视频。后端需要二进制文件,所以需要进行转换。参考链接:blog.csdn.net/weixin_4413…
// bae64转文件对象
function dataURLtoFileFun (dataurl, filename) {
// 将base64转换为文件,dataurl为base64字符串,filename为文件名(必须带后缀名,如.jpg,.png)
const arr = dataurl.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}
-
上传服务器
使用axios进行上传,但是上传文件的话需要进行配置,如下
const token = getToken() const instance = axios.create({ baseURL: process.env.VUE_APP_URL, headers: { //自定义token字段 Authorization: token, //重要字段,使用formData提交 'Content-Type': 'multipart/form-data' }, //这个是看了一个链接说,axios拦截器会把文件形式转成对象格式,就会上传失败,链接在下面: transformRequest: [ function (data) { return data } ] })
transformRequest参考链接: www.cnblogs.com/czy960731/p…
注意:因为我项目中接口都是会经过axios拦截器的,据说会把文件流转成对象,于是我就创建了一个新的axios副本。
调用接口:
// 参数为单个文件 function upLoaderImg (file, fileTimestamp) { // file为 你读取成功的回调文件信息,fileTimestamp为时间戳(后端要求的) // new 一个FormData格式的参数 const fromData = new FormData() fromData.append('file', dataURLtoFileFun(file.content, file.file.name)) fromData.append('fileTimestamp', fileTimestamp) return new Promise((resolve, reject) => { // 把 uploadUrl 换成自己的 上传路径 instance .post('uploadUrl', fromData) .then(res => { console.log('看下是否上传成功', res) if (res && res.data && res.data.status === 1) { // 如果为真 resolve出去 resolve(res.data) } else { // 否则 Toast 提示 Toast.fail(res.data && res.data.msg) reject(res.data) } }) .catch(err => { Toast.fail('系统异常') reject(err) }) }) }
-
上传多个文件
原本以为是以数组的形式去上传多个文件,单个文件作为数组的一个文件对象元素,结果行不通,也不知道是哪儿错了,大概率是这种形式不能通过formData提交。
然后去看了element-ui封装好的文件上传形式,是支持多个文件上传的,但是他的形式是,每个文件发送一个上传请求,于是我也这样做好了哈哈哈哈哈哈