業務場景
微信端項目是基于Vux + Axios構建的,關于圖片上傳的業務場景有以下幾點需求:
1、單張圖片上傳(如個人頭像,實名認證等業務)
2、多張圖片上傳(如某類工單記錄)
3、上傳圖片時期望能按指定尺寸壓縮處理
4、上傳圖片可以從相冊中選擇或者直接拍照
遇到的坑
采用微信JSSDK上傳圖片
在之前開發的項目中(mui + jquery),有使用過微信JSSDK的接口上傳圖片,本想應該能快速遷移至此項目。事實證明編程沒有簡單的事:
1、按指定尺寸壓縮圖片
JSSDK提供的接口wx.chooseImage 是不能指定圖片壓縮尺寸的,只能在后端的接口通過localId獲取圖片時,再轉換成指定的尺寸。
2、微信JSSDK的接口權限驗證
只要是單頁面應用項目,微信JSSDK注入權限驗證都會有這個坑,而這個與路由模式(hash 或 history)也有關聯。有關此坑, 后續會再次寫文總結。參考解決方案 [微信JSSDK] 解決SDK注入權限驗證 安卓正常,IOS出現config fail
經過權衡考慮網頁可能需要在微信以外的瀏覽器上也能上傳文件,顧后來放棄了采用微信JSSDK接口上傳圖片的方式。
android版微信,input onchange事件不觸發
這個坑,圈內有很多人踩過了。在PC端測試是正常的,發布之后,微信端上傳時能選擇文件,但之后沒有任何效果。日志跟蹤,后臺的api都未調用,由此判斷是input的onchange事件未被觸發。
解決方案, 更改input的 accept屬性:
<input ref="file" type="file" accept="image/jpeg,image/png" @change="selectImgs" />
將以上代碼更改為:
<input ref="file" type="file" accept="image/*" @change="selectImgs" />
如果不允許從相冊中選擇,只能拍照,增加capture="camera":
<input ref="file" type="file" accept="image/*" capture="camera" @change="selectImgs" />
(注:如果場景支持從相冊選擇或拍照,測試發現某些機型拍照后返回到了主頁。哈哈,也有可能是其他因素引起的問題,未做深究了)
使用Lrz.js壓縮圖片
目前手機拍照的圖片文件大小一般在3-4M,如果在上傳時不做壓縮處理會相當浪費流量并且占用服務器的存儲空間(期望上傳原圖的另做討論)。如果能夠在前端壓縮處理,那肯定是最理想的方案。而 lrz.js 則提供了前端圖片文件的壓縮方案,并且可以指定尺寸壓縮。實測:3M左右的圖片文件,按寬度450px尺寸壓縮上傳后的文件大小在500kb左右,上傳時間2s以內。
其核心源碼,如下:
selectImgs () { let file = this.$refs.file.files[0] lrz(file, { width: 450, fieldName: 'file' }).then((rst) => { var xhr = new XMLHttpRequest() xhr.open('POST', 'http://xxx.com/upload') xhr.onload = () => { if (xhr.status === 200 || xhr.status === 304) { // 無論后端拋出何種錯誤,都會走這里 try { // 如果后端跑異常,則能解析成功, 否則解析不成功 let resp = JSON.parse(xhr.responseText) console.log('response: ', resp) } catch (e) { this.imageUrl = xhr.responseText } } } // 添加參數 rst.formData.append('folder', 'wxAvatar') // 保存的文件夾 rst.formData.append('base64', rst.base64) // 觸發上傳 xhr.send(rst.formData) return rst })}
新聞熱點
疑難解答