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.rzrgm.cn/tylerdonet/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,如有問題,請微信聯系冬天里的一把火
浙公網安備 33010602011771號