Categories
程式開發

H5選圖預覽到上傳最佳實踐


一背景

在金融性質的App裡,選擇本地相冊圖片或者拍照,然後預覽並且上傳是一個典型的使用場景,比如常見的身份證信息上傳。在最近接觸的幾家銀行客戶裡,都反饋有類似的場景,並且在使用上都或多或少的遇到一些問題,最後找到我們,希望我們提供一些最佳實踐。在這里分享下對應場景的一些優化解決方案。

二方案介紹

我們先介紹下各個銀行的傳統方案都是怎麼做的,以及存在的問題。

1. 選圖方案

1.1 方案1:使用Android原生Webview

方案介紹:前端通過input標籤,指定type=file,通過原生webview的支持實現選擇文件。

Android原生webView並不支持選擇文件上傳,需要外殼自己擴展WebChromeClient裡的openFileChooser或者onShowFileChooser,然後去喚起系統選擇文件彈框,選擇文件會使用系統提供的組件或者其他支持的app,返回的uri有的直接是文件的url,有的是contentprovider的uri,需要統一處理一下返回uri格式。這種方案存在以下問題

外殼定制實現的邏輯較多,還需要對系統不同文件選擇器返回的地址做兼容,容易有兼容性問題選擇文件實現依賴系統的文件選擇器,不同手機實現不一致,無法做到統一

1.2 方案2:使用mPaas的H5容器

如果業務使用了mPaas的H5容器後,雖然容器內已經內置了喚起文件選擇器的一系列操作,但是還是一樣存在系統文件選擇器不可控的風險。比如如果業務希望選擇的是一張圖片,但是喚起後的效果可能是下面這個樣子,很多客戶也是無法接受的。

H5選圖預覽到上傳最佳實踐 1

1.3 方案3:實現jsapi喚起Native自定義的選圖頁面

這種方案就是利用H5容器提供的自定義jsapi的能力,自定義一個選圖的jsapi,然後前端去調用,去喚起Native自己實現的選圖頁面,最後結果通過base64的形式返回給前端做顯示。這樣就解決了前面提到系統選擇文件不可控的問題。

但是當這個方案上線後,還是遇到了一些問題,主要因為通過jsbridge只能返回json,所以圖片數據是通過base64的形式返回的。但是因為有多選的場景,如果用戶選擇了多張圖片後,返回的base64數據會特別大,導致在一些低端設備上有一些OOM的問題,同時大量base64轉JSON的過程中,也會出現ANR。所以也是不能上線的。

1.4 方案4:選圖返回本地路徑,webview攔截訪問本地資源

為了解決前面提到的返回base64存在的穩定性問題,所以我們在選圖的時候,是返回了一個本地的地址,然後Native模塊攔截webview的資源訪問,去本地拿到對應的圖片返回給webview顯示。比如選圖後返回給webview的地址是:https://www.mPaas.com.cn/mpaas.jpg“,www.mPaas.com.cn“是我們自定義的一個域名,我們攔截這個特定自定義域名,然後去本地相冊去找mpaas.jpg“對應的圖片攔截返回。通過這樣的一個轉換邏輯,解決了base64傳遞的問題。

2. 文件上傳方案

通過以上的描述,我們對比了各種選圖方案實現的優缺點,最後沉澱了最佳實踐。選圖實現了後,下一步就是上傳。對於上傳也經歷了類似的方案演進。

2.1 方案1:使用RPC接口上傳

對於使用了mPaas的用戶,第一步想到的肯定是通過RPC接口實現文件的上傳,但是在實際驗證過程中,我們發現對於一些比較大的圖片上傳,RPC接口直接返回了403的報錯,Http Transport error[413] : Request Entity Too Large]. 很明顯是因為文件過大導致服務端掛掉了。主要因為RPC的定位是用做業務數據通道,一般建議的大小是200K以內,對於直接上傳大文件的數據,會有穩定性風險,甚至因為這個把整個網關打掛。

H5選圖預覽到上傳最佳實踐 2

2.2 方案2:使用OSS方案上傳

對於類似的文件上傳場景,建議是直接使用OSS的方案進行上傳,比如常見的阿里雲OSS方案:https://help.aliyun.com/product/31815.html“。OSS是專門為解決文件存儲整條鏈路設計的一套方案,解決了文件上傳的各種場景,用戶可以集成對應的Android和iOS的SDK實現對本地文件的上傳。

三總結

僅僅是一個選圖上傳預覽這樣一個場景,就可以有這麼多不同的方案演進,沒有最好的方案,只有最合適的方案。阿里雲金融線專家服務團隊為金融App提供最佳解決方案,歡迎大家了解。