van-uploader拍照上传多个文件报错ERR_UPLOAD_FILE_CHANGED问题
移动端使用van-uploader连续上传两个图片,ajax接口也会出现报错ERR_UPLOAD_FILE_CHANGED,这个地方还真要用到上一篇提供的方案,先把图片转成base64字符串,上传前再转成File对象。
1.问题描述
同上一篇el-upload拍照上传多个文件报错 ERR_UPLOAD_FILE_CHANGED问题,移动端使用van-uploader选择多个文件一起上传也遇到这个问题,报错也一样:ERR_UPLOAD_FILE_CHANGED
2.问题分析
这里的问题是浏览器兼容性问题,我用红米手机自带浏览器连续拍多张图片,一起上传没有这个问题,Android套壳之后就不行,估计Android套壳使用的浏览器和红米浏览器的内核不一样,前者不支持这个特性,参考下面参考链接。
3.解决方案
拍照选择文件的时候把文件转成base64字符串同时清除input框内容,点确定的时候把base字符串还原成文件,然后传给外面组件,这里是用store保存并传数据的。
van-uploader和el-upload有点区别,前者只有after-read,befor-read事件,没有fiechange事件,这里使用原生的input标签来实现这个功能。
javascript关键代码:
//图片转base64
const fileToBase64 = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result)
reader.onerror = (error) => reject(error)
})
}
// base64转图片
const base64ToFile = (base64: any, fileName: any) => {
const arr = base64.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 })
}
html关键代码:
<div class="full-screen list-container">
<div class="content-wrapper photo-wrapper" :style="{marginTop: contentTop + 'px'}">
<!-- <van-uploaderer v-model="photoStore.photoList" multiple/> -->
<div class="container" @click="onClickPicture">
<img class="image_picture" :src="getAssetURL('icon_picture.png')"/>
<div class="text">上传</div>
</div>
<input type="file" ref="refInput" accept="image/*" @change="onFileChange" class="file-packer" id="uploadFile" hidden>
</div>
<div class="image-wrapper">
<div v-for="(item, index) in obj.fileList" :key="index" class="image-item">
<img :src="item.img" alt="" class="item"/>
<img :src="getAssetURL('icon_delete_photo.png')" alt="" class="delete" @click="onDelClick(index)"/>
</div>
</div>
<div class="footer-wrapper">
<div class="btn-box">
<van-button type="primary" @click="onOk">确定</van-button>
</div>
</div>
</div>
const onFileChange = e => {
fileToBase64(e.target.files[0]).then(res => {
obj.fileList.push({img: res, name: e.target.files[0].name})
refInput.value.value = ''
})
}
const onOk = () => {
const files = obj.fileList.map((item, i) => {
return {file: base64ToFile(item.img, `_${i + 1}_${item.name}`),img: item.img}
})
photoStore.setPhotoList(files)
refInput.value.value = ''
router.back()
}
最后结果:
4.总结
文件上传虽然可以使用html+javascript来实现,但是由于浏览器差异还是有很多的差异和兼容性问题。
作者:Tyler Ning
出处:http://www.cnblogs.com/tylerdonet/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,请微信联系冬天里的一把火