国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android 開發 使用WebUploader解決安卓微信瀏覽器上傳圖片中遇到的bug

2019-12-12 04:38:40
字體:
來源:轉載
供稿:網友

先給大家分析下微信瀏覽器上傳圖片bug的原因

微信在新版本中采用的是自己的X5內核瀏覽器,而在較老的版本中還有可能是安卓的原生瀏覽器。具體的環境我也不太了解,但是經過實際多臺安卓機型的測試,我采取的方案可以基本確保在安卓機中微信瀏覽器的成功上傳。蘋果機型沒問題,因為微信的ios客戶端使用的是Safari的內核,沒有各種坑,且效果最好。

這里給出一個 WebUploader 官方關于移動端適配的 issues 鏈接。里面提供的方法確實有效,但就是解決的方案并沒有很清楚的展示出來,從該issues中有好幾個人用戶提出如何修改就能知道了。

開始時遇到的問題

環境

后臺使用 Spring MVC [V 4.08],前端使用一個開源的 HTML5 框架

問題

ios可完美上傳,安卓手機一半以上不太支持,出現進度條卡死,圖片無法上傳成功而且只能上傳png格式圖片的問題(后來證明是由于壓縮失敗引起的,在解決中詳細指出)。發布到服務器上正式運營以后,發現部分用戶只填寫了文字信息,無法上傳圖片,不好統計數據,但是這樣的 BUG 率顯然是不行的,接下來就給出我的解決方案吧,經過實際測試應該是沒問題的,不保證完全有效,因為原理不是太清楚,僅供參考。

后來的解決方案

第一步,sendAsBinary: true

我先是按照 issues 中給出的第一個解決方法,設置 sendAsBinary: true,后臺不做任何修改的情況下會產生 500 的錯誤,但是此時解決了進度條卡死的問題(當然啊!圖片直接就上傳失敗了!)……根據issues中 2betop 的回答,此時獲取文件應該是直接獲取文件的二進制流。

之前獲取圖片的方式是使用 Spring 自帶的 MultipartHttpServletRequest 將 HttpServletRequest 的實例 request 轉換,然后獲取多個文件的信息。下方代碼根據實際代碼刪減不必要的細枝末節得出。

MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;// 獲取上傳文件的列表Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();// 圖片上傳前的原始名String originalName;// 循環獲取多文件上傳時文件列表中的每個文件對象for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {// 上傳文件MultipartFile mf = entity.getValue();// 文件上傳前的原始名originalName = mf.getOriginalFilename();// 文件擴展名String fileExt = originalName.substring(originalName.lastIndexOf(".") + 1).toLowerCase();// 文件的絕對路徑FileFile uploadFile = new File(uploadAbsolutePath + "/" + newName);try {FileCopyUtils.copy(mf.getBytes(), uploadFile);} catch (IOException ioException) {logger.error("圖片保存到文件夾中出錯!", ioException);} catch (Exception e) {logger.error("文件沒有復制到指定的目錄下", e);}}

這是原本的獲取方式,500 報錯時指示是第一行代碼出錯,無法轉換,因為此時 WebUploader 在設置了 sendAsBinary: true后 并沒有使用 content-type: multipart/form-data 上傳文件,而是 content-type: application/ocet-stream,源碼中也是這么寫的,但是實際獲取的請求頭中并沒有看到這個字段,而只是圖片的類型.下列給出我使用 Chrome 的 devTools 保存下來的請求信息,只貼出 headers 中的字段值(針對同一個上傳 API 提出請求):

500 錯誤時的請求頭

"url": "http://localhost:8787/lostFound/front/release/upload?releaseType=0&orderId=330&id=WU_FILE_1&name=20140120_035024000_iOS.jpg&type=image%2Fjpeg&lastModifiedDate=Sat+Jan+31+2015+01%3A32%3A34+GMT%2B0800+(%C3%A4%C2%B8%C2%AD%C3%A5%C2%9B%C2%BD%C3%A6%C2%A0%C2%87%C3%A5%C2%87%C2%86%C3%A6%C2%97%C2%B6%C3%A9%C2%97%C2%B4)&size=81666","httpVersion": "HTTP/1.1","headers": [{"name": "Origin","value": "http://localhost:8787"},{"name": "Accept-Encoding","value": "gzip, deflate"},{"name": "Host","value": "localhost:8787"},{"name": "Accept-Language","value": "zh-CN,zh;q=0.8"},{"name": "User-Agent","value": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1"},{"name": "Content-Type","value": "image/jpeg"},{"name": "Accept","value": "*/*"},{"name": "Referer","value": "http://localhost:8787/lostFound/"},{"name": "Cookie","value": "JSESSIONID=2839511C91E9ECE62D155C6EE18F3259; JSESSIONID=64B53863E1C7D82B96927F298A864E18"},{"name": "Connection","value": "keep-alive"},{"name": "Content-Length","value": "81666"}],"queryString": [{"name": "releaseType","value": "0"},{"name": "orderId","value": "330"},{"name": "id","value": "WU_FILE_1"},{"name": "name","value": "20140120_035024000_iOS.jpg"},{"name": "type","value": "image%2Fjpeg"},{"name": "lastModifiedDate","value": "Sat+Jan+31+2015+01%3A32%3A34+GMT%2B0800+(%C3%A4%C2%B8%C2%AD%C3%A5%C2%9B%C2%BD%C3%A6%C2%A0%C2%87%C3%A5%C2%87%C2%86%C3%A6%C2%97%C2%B6%C3%A9%C2%97%C2%B4)"},{"name": "size","value": "81666"}],"bodySize": 0

在不修改 sendAsBinary: true 之前成功上傳的請求頭

"url": "http://localhost:8787/lostFound/front/release/upload","httpVersion": "HTTP/1.1","headers": [{"name": "Origin","value": "http://localhost:8787"},{"name": "Accept-Encoding","value": "gzip, deflate"},{"name": "Host","value": "localhost:8787"},{"name": "Accept-Language","value": "zh-CN,zh;q=0.8"},{"name": "User-Agent","value": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1"},{"name": "Content-Type","value": "multipart/form-data; boundary=----WebKitFormBoundaryLeVpfViKLf1xLdIr"},{"name": "Accept","value": "*/*"},{"name": "Referer","value": "http://localhost:8787/lostFound/"},{"name": "Cookie","value": "JSESSIONID=A76C40D04276501F54675AA02AE61467; JSESSIONID=64B53863E1C7D82B96927F298A864E18"},{"name": "Connection","value": "keep-alive"},{"name": "Content-Length","value": "44210"}],"queryString": [],"bodySize": 929,

比較兩者的區別,發現區別:

content-type: 修改為 sendAsBinary: true 以后,這個值變為 image/jpeg, 而之前是 multipart/form-data,所以不能再使用 MultipartHttpServletRequest,后端獲取改為獲取文件流。

queryString:啟用二進制上傳以后,參數直接添加到 Url 中。

bodySize:啟用之后變為 0,啟用之前不為 0

先修改后端獲取方式,代碼更改如下:

File file = new File(uploadAbsolutePath);if (!file.exists() && !file.mkdirs()) {// 如果file對象不存在,那么就將該對象的路徑名中不存在的文件夾目錄建立出來}// 文件擴展名String fileExt = name.substring(name.lastIndexOf(".") + 1).toLowerCase();// 文件的絕對路徑FileFile uploadFile = new File(uploadAbsolutePath + "/" + newName);try {// 將上傳的圖片二進制流保存為文件FileCopyUtils.copy(request.getInputStream(), new FileOutputStream(uploadFile));} catch (IOException ioException) {logger.error("圖片保存到文件夾中出錯!", ioException);} catch (Exception e) {logger.error("文件沒有復制到指定的目錄下" ,e);}

此時后端就能夠獲取前端上傳的圖片了,ios 機型(iPhone 6s)依然沒問題,安卓上傳png格式的圖片沒有任何問題,但是jpg依然無法上傳。在后端的時候,打印 request 的 headers,發現安卓機型上傳jpg圖片是會丟失 content-type,值為空。結合 issues 中的判斷,也許是安卓機型在壓縮 jpg 格式圖片時出了問題,先解決再試試看!

第二步:加上androidpatch

根據官方說明,使用 webuploader.custom.js,其中將 runtime/html5/androidpatch.js 打包了進來。

然后在沒有修改任何代碼的情況下,經過五個手機的測試,新老機型:華為榮耀、魅藍、聯想等等的測試,安卓機可以在微信中隨意上傳圖片了。這是個大坑啊!說明無法上傳 jpg 格式圖片的原因竟是壓縮 jpg 格式圖片的時候出錯,導致進度條卡死,上傳失敗。

總結使用心得

按照以上的總結,我想下一次我應該能再一次利用這一次的經驗解決微信上傳圖片的坑了~也懂得從request 的 headers 中尋找 bug 發生的原因,WebUploader 是個很優秀的開源插件,源碼也寫的很有條理,清晰易讀,雖然我并沒有讀完。現在閱讀框架源碼是越來越輕松了,加油,下個目標是正在學習的 React.js。

以上所述是小編給大家介紹的Android 開發 使用WebUploader解決安卓微信瀏覽器上傳圖片中遇到的bug,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 静海县| 瑞金市| 定兴县| 尉氏县| 子长县| 漳浦县| 讷河市| 承德市| 博乐市| 平舆县| 华安县| 竹溪县| 怀宁县| 山西省| 福贡县| 北碚区| 大同市| 雅江县| 疏附县| 通道| 手游| 桃园县| 普宁市| 类乌齐县| 隆回县| 渑池县| 体育| 城固县| 绍兴县| 保康县| 雷波县| 勐海县| 凤阳县| 肥乡县| 蒙城县| 清苑县| 克什克腾旗| 周至县| 周至县| 思南县| 高要市|