摘要:具體的環境我也不太了解,但是經過實際多臺安卓機型的測試,我采取的方案可以基本確保在安卓機中微信瀏覽器的成功上傳。
摘自個人博客:走啊走的記錄,歡迎點擊查看,效果更佳!
微信瀏覽器上傳圖片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; // 獲取上傳文件的列表 MapfileMap = multipartRequest.getFileMap(); // 圖片上傳前的原始名 String originalName; // 循環獲取多文件上傳時文件列表中的每個文件對象 for (Map.Entry entity : fileMap.entrySet()) { // 上傳文件 MultipartFile mf = entity.getValue(); // 文件上傳前的原始名 originalName = mf.getOriginalFilename(); // 文件擴展名 String fileExt = originalName.substring(originalName.lastIndexOf(".") + 1).toLowerCase(); // 文件的絕對路徑File File 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(); // 文件的絕對路徑File File 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。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79143.html
摘要:之前實習做的一個移動端的頁面需要的功能有圖片上傳點擊客戶端的返回按鈕有提示即與客戶端有交互遇到不少的坑總結一下問題圖片上傳功能使用工具百度的暫時遇到的坑刪除圖片實際上并沒有完全刪除需要自己在源碼上添加詳情看的提問上傳的圖片旋轉角度有問題比 之前實習做的一個移動端的頁面 需要的功能有圖片上傳 點擊客戶端的返回按鈕 有提示(即與客戶端有交互) 遇到不少的坑 總結一下問題 1.圖片上傳功能 ...
摘要:簡介是由團隊開發的一個簡單的以為主,為輔的現代文件上傳組件。采用大文件分片并發上傳,極大的提高了文件上傳效率。另外分片傳輸能夠更加實時的跟蹤上傳進度。選擇文件的按鈕。 簡介:WebUploader是由Baidu WebFE(FEX)團隊開發的一個簡單的以HTML5為主,FLASH為輔的現代文件上傳組件。在現代的瀏覽器里面能充分發揮HTML5的優勢,同時又不摒棄主流IE瀏覽器,沿用原來的...
摘要:簡介是由團隊開發的一個簡單的以為主,為輔的現代文件上傳組件。采用大文件分片并發上傳,極大的提高了文件上傳效率。另外分片傳輸能夠更加實時的跟蹤上傳進度。選擇文件的按鈕。 簡介:WebUploader是由Baidu WebFE(FEX)團隊開發的一個簡單的以HTML5為主,FLASH為輔的現代文件上傳組件。在現代的瀏覽器里面能充分發揮HTML5的優勢,同時又不摒棄主流IE瀏覽器,沿用原來的...
摘要:簡介是由團隊開發的一個簡單的以為主,為輔的現代文件上傳組件。采用大文件分片并發上傳,極大的提高了文件上傳效率。另外分片傳輸能夠更加實時的跟蹤上傳進度。選擇文件的按鈕。 簡介:WebUploader是由Baidu WebFE(FEX)團隊開發的一個簡單的以HTML5為主,FLASH為輔的現代文件上傳組件。在現代的瀏覽器里面能充分發揮HTML5的優勢,同時又不摒棄主流IE瀏覽器,沿用原來的...
閱讀 2000·2021-09-13 10:23
閱讀 2332·2021-09-02 09:47
閱讀 3792·2021-08-16 11:01
閱讀 1214·2021-07-25 21:37
閱讀 1597·2019-08-30 15:56
閱讀 522·2019-08-30 13:52
閱讀 3127·2019-08-26 10:17
閱讀 2442·2019-08-23 18:17