網站在Webview模式的踩雷經驗
前言
有的時候整個專案會因為為了節省App開發成本
會將某些功能例如登入、會員、註冊使用webview完成
並透過JavascriptInterface或flutter來做App跟webview之間的溝通
但這個過程中會出現一堆一般web開發不會遇到的問題
以下將依序紀錄說明
Apple相關問題
Apple堅持只要是IOS App中有第三方登入的功能
一定要實做Apple ID登入
並且還要將Apple登入放在第一順位
Google Ouath問題
403 disabled user agent
Google Oauth會擋mobile的useragent
導致這個錯誤
因此要使用setUserAgentString這個method來調整webview啟動的useragent
參考影片(5:57左右)
Google登入在輸入帳號密碼頁面會顯示瀏覽器不安全的問題
一樣是useragent的問題
以下為測試過確認ok可以使用的useragent值
Mozilla/5.0 (Linux; Android 8.0.0; SM-C900Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.105 Mobile Safari/537.36
小心App去覆寫原生JS導致錯誤
照理來說這個不該發生因為真的很瞎
但在開發經驗上
居然還是遇到
原因是App開發人員在webview啟動後去改寫原生的console.log、console.warn功能
導致web用到這些原生console功能的地方
直接噴console.warn is not a function的錯誤
導致一堆流程直接炸掉
Java的callback參數或回傳型態要確認好
有的時候會因為丟進callback的型態不正確
導致明明有丟值進callback
app卻一直接不到值
原因是因為Java在執行callback的時候發現值不對會直接變成null
Java bridge method can't be invoked on a non-injected object
這個是安卓的JavascriptInterface callback call不到的錯誤訊息
這個不是每次安卓開發都會遇到的問題
但就有時候會遇到不確定是否為安卓開發人員寫法不同導致的
總之
遇到這個問題web寫法需要在callback外面再包一層method
不能直接call
例如原本的方法
window.JavascriptInterface[methodName](...args)
要改成
const callback = (...args) => {
return window.JavascriptInterface[methodName](...args)
}
開發過程debug建議
獨立debug頁面方便隔離測試
在使用webview的開發上常常會遇到問題
然後看不出是App還是Web哪邊的問題
因此我自己都是會獨立一個webview debug頁面
這個頁面可以獨立測試JavascriptInterface、flutter的callback
遇到問題的時候來這個頁面先call測試的callback
將問題獨立開來方便debug
web開發時先寫一個mock的JavascriptInterface
並可以透過指定的localstorage啟用這個mock的JavascriptInterface
來確保該call的時候有正常call到method
class mockJavascriptInterface {
getFingerprint(fingerprint) {
console.warn('[Webview Callback] getFingerprint', fingerprint)
}
getToken(token) {
console.warn('[Webview Callback] getToken', token)
}
getEnduringToken(token) {
console.warn('[Webview Callback] getEnduringToken', token)
}
loginSuccessfully() {
console.warn('[Webview Callback] loginSuccessfully')
}
}
windows.JavascriptInterface = new mockJavascriptInterface()