前陣子的一個專案,客戶反應很多使用者用手機操作時,網頁會有錯誤導致無法註冊。但我手機實測的結果又沒有發生任何問題,於是請客戶提供使用者的操作環境,例如 Android 或 iOS 系統,瀏覽器版本等等。
結果都不是這些原因,最後才發現是因為使用者在 Line 上面開啟網站連結所引起。當 Line 點擊連結時,並不會呼叫手機的預設瀏覽器(例如 Chrome、Safari 等),而是會開啟內建瀏覽器,專有名詞叫做 In-App browser,或是 webview。
這件事就非常麻煩了,因為內建瀏覽器並不像主流瀏覽器能支援最新的網頁技術、JS 或 CSS 語法等等,要 Debug 問題也是非常麻煩的事。
偏偏客戶的使用者有很大的比例會操作 Line,所以解決網頁在「內建瀏覽器」上的問題,變成一件必要且急迫的事。
先說結論,研究半天後發現,這件事以目前的技術,沒有治本的解法,只能先用治標的方式撐著,等待科技的進步來化解這個麻煩,或是看能否有消滅「內建瀏覽器」這個產物的可能性。
(圖片出處: pixabay.com)
前端工程師已經夠悲情了,要應付 PC 網頁、各種行動裝置的眾家瀏覽器(及不同版本)的網頁效果,現在竟然還有手機「內建瀏覽器」這個大魔王。
為何說是大魔王呢?以前多半只要告訴客人 "請使用主流瀏覽器,才能支援最新的網頁技術,獲得最佳效果",但現在這句話已經無法輕易打發客人了,因為越來越多手機 APP 在開啟網頁連結時,都不呼叫外部瀏覽器,反而一律使用「內建瀏覽器」,例如 Line、FB、twitter、instagram、微信....等等族繁不及備載。
可參考這篇「關於 WebView: 10 件你需要知道的事」,實際上手機的 "內建瀏覽器"並不具備完整的瀏覽器功能,所以前端開發者也不太可能用這個環境來開發網頁。
那為何這個殘缺的瀏覽器,卻成為眾多手機 APP 的最愛,一定要用內建瀏覽器來開啟網頁,不惜犧牲使用者體驗呢?
原本跟客戶說這是 Line 的問題,不是我們網頁的問題,還想說請客戶去跟 Line 抗議,要求取消強制用內建瀏覽器來開啟網頁。
不過大概爬了一下文後,就知道這是不可能的事,APP 不會放棄使用內建瀏覽器,原因大致是這樣:
既然「內建瀏覽器」已經確定成為前端開發者的夢魘,那麼必須試著與惡魔相處。
雖無法百戰百勝,但知己知彼仍是非常必要,這篇「你知道你的網站可能在 InAppBrowser/webview 無法使用嗎?」是前端開發者必讀的一篇整理:
1. 沒有治本之道
如果能夠有一個 js 判斷方式,偵測到「內建瀏覽器」時作對應的處置,相信這可以算是 "治本"的方法。
可惜的是,測試了大部分 Google 到的語法,多半都沒有作用,這代表:
2. 後端處理語法
這個 Github 上的專案,可用來偵測 APP 是否呼叫內建瀏覽器:
不過是用來裝在後端,所以我不清楚效果如何。
而且如前面我說的,除非這個專案持續有人不斷在維護,否則隨著網頁技術、環境改變,語法可能就失效了。
3. 變通作法
最後是退而求其次的作法,也是我採用的方法,針對客群使用者環境處理。例如 Line 的使用者族群較多,就偵測是否使用 Line 開啟內建瀏覽器。
參考這篇「檢查目前瀏覽器的版本」,提供了 3 種檢測手機 APP 是否開啟內建瀏覽器的語法:
以我客戶的狀況為例,使用者在手機用 Line 開啟連結後會導致特定管道的登入功能失效,那麼可以使用 isLineApp 來偵測是否用 Line 開啟內建瀏覽器。當偵測到時,關閉「特定管道的登入/註冊」的功能來減少不良的用戶體驗。
由於手機的 APP 太多了,且不會知道將來要流行什麼 APP,所以目前真的只能看到一個洞、塞一個洞。但麻煩的是,有些洞是堵不起來的。
這個 stackoverflow 討論串「How to detect pages when a user browses inside twitter in app?」,有人提出 twitter 要如何偵測呼叫內建瀏覽器,可惜答案是 "不可能",因為 twitter 沒有針對 webview 這件事,在 navigator.userAgent 塞相關字串。
我們需要慶幸的是,至少一些使用率較高的 APP,例如 FB、Line 等,會在 navigator.userAgent 塞字串讓我們判別。將來如果有使用者回報網頁在某些 APP 執行異常時,前端工程師們再想辦法 Google 該內建瀏覽器的偵測字串吧!
結果都不是這些原因,最後才發現是因為使用者在 Line 上面開啟網站連結所引起。當 Line 點擊連結時,並不會呼叫手機的預設瀏覽器(例如 Chrome、Safari 等),而是會開啟內建瀏覽器,專有名詞叫做 In-App browser,或是 webview。
這件事就非常麻煩了,因為內建瀏覽器並不像主流瀏覽器能支援最新的網頁技術、JS 或 CSS 語法等等,要 Debug 問題也是非常麻煩的事。
偏偏客戶的使用者有很大的比例會操作 Line,所以解決網頁在「內建瀏覽器」上的問題,變成一件必要且急迫的事。
先說結論,研究半天後發現,這件事以目前的技術,沒有治本的解法,只能先用治標的方式撐著,等待科技的進步來化解這個麻煩,或是看能否有消滅「內建瀏覽器」這個產物的可能性。
(圖片出處: pixabay.com)
一、什麼是內建瀏覽器
前端工程師已經夠悲情了,要應付 PC 網頁、各種行動裝置的眾家瀏覽器(及不同版本)的網頁效果,現在竟然還有手機「內建瀏覽器」這個大魔王。
為何說是大魔王呢?以前多半只要告訴客人 "請使用主流瀏覽器,才能支援最新的網頁技術,獲得最佳效果",但現在這句話已經無法輕易打發客人了,因為越來越多手機 APP 在開啟網頁連結時,都不呼叫外部瀏覽器,反而一律使用「內建瀏覽器」,例如 Line、FB、twitter、instagram、微信....等等族繁不及備載。
可參考這篇「關於 WebView: 10 件你需要知道的事」,實際上手機的 "內建瀏覽器"並不具備完整的瀏覽器功能,所以前端開發者也不太可能用這個環境來開發網頁。
那為何這個殘缺的瀏覽器,卻成為眾多手機 APP 的最愛,一定要用內建瀏覽器來開啟網頁,不惜犧牲使用者體驗呢?
二、為何 APP 要用 webview
原本跟客戶說這是 Line 的問題,不是我們網頁的問題,還想說請客戶去跟 Line 抗議,要求取消強制用內建瀏覽器來開啟網頁。
不過大概爬了一下文後,就知道這是不可能的事,APP 不會放棄使用內建瀏覽器,原因大致是這樣:
- 使用外部瀏覽器後,使用者注意力一分散,就會忘了回到 APP
- APP 死命也要將使用者注意力留住,而內建瀏覽器按右上角關閉後,會立即回到 APP
- 使用外部瀏覽器開啟時間長,而內建瀏覽器輕薄短小,開啟速度快,回到 APP 也快
- 使用外部瀏覽器後,蒐集不到使用者的數據
- 在 APP 內執行 webview,所有使用者行為都被 APP 掌握
- 掌握使用者行為的數據,不會輕易被 APP 放棄
三、內建瀏覽器會產生什麼問題
既然「內建瀏覽器」已經確定成為前端開發者的夢魘,那麼必須試著與惡魔相處。
雖無法百戰百勝,但知己知彼仍是非常必要,這篇「你知道你的網站可能在 InAppBrowser/webview 無法使用嗎?」是前端開發者必讀的一篇整理:
- 購物網站會發生的問題
- 哪些基本的 JS 語法無法執行
- 哪些語法執行效果跟網頁不一樣
- 提供一個測試網頁,可用來測試各種 APP 開啟連結的效果
四、解決方法
1. 沒有治本之道
如果能夠有一個 js 判斷方式,偵測到「內建瀏覽器」時作對應的處置,相信這可以算是 "治本"的方法。
可惜的是,測試了大部分 Google 到的語法,多半都沒有作用,這代表:
- 網頁技術不斷在更新
- 行動裝置作業系統不斷在升級
- 一些過去可行的判斷語法,會隨著時間失效
- 就算目前找到了可行的語法,也可能一段時間後就無效
2. 後端處理語法
這個 Github 上的專案,可用來偵測 APP 是否呼叫內建瀏覽器:
不過是用來裝在後端,所以我不清楚效果如何。
而且如前面我說的,除非這個專案持續有人不斷在維護,否則隨著網頁技術、環境改變,語法可能就失效了。
3. 變通作法
最後是退而求其次的作法,也是我採用的方法,針對客群使用者環境處理。例如 Line 的使用者族群較多,就偵測是否使用 Line 開啟內建瀏覽器。
參考這篇「檢查目前瀏覽器的版本」,提供了 3 種檢測手機 APP 是否開啟內建瀏覽器的語法:
(function() {
var u = navigator.userAgent,
ua = navigator.userAgent.toLowerCase(),
isLineApp = u.indexOf("Line") > -1, // Line 內建瀏覽器
isFbApp = u.indexOf("FBAV") > -1, // FB App 內建瀏覽器
isWeixinApp = ua.match(/MicroMessenger/i) == "micromessenger"; // 微信內建瀏覽器
// 如果是 Line 內建瀏覽器
if (isLineApp) {
// do sth
}
// 如果是 FB App 內建瀏覽器
if (isFbApp) {
// do sth
}
// 如果是 微信內建瀏覽器
if (isWeixinApp) {
// do sth
}
})();
以我客戶的狀況為例,使用者在手機用 Line 開啟連結後會導致特定管道的登入功能失效,那麼可以使用 isLineApp 來偵測是否用 Line 開啟內建瀏覽器。當偵測到時,關閉「特定管道的登入/註冊」的功能來減少不良的用戶體驗。
五、沒有完美的解決方案
由於手機的 APP 太多了,且不會知道將來要流行什麼 APP,所以目前真的只能看到一個洞、塞一個洞。但麻煩的是,有些洞是堵不起來的。
這個 stackoverflow 討論串「How to detect pages when a user browses inside twitter in app?」,有人提出 twitter 要如何偵測呼叫內建瀏覽器,可惜答案是 "不可能",因為 twitter 沒有針對 webview 這件事,在 navigator.userAgent 塞相關字串。
我們需要慶幸的是,至少一些使用率較高的 APP,例如 FB、Line 等,會在 navigator.userAgent 塞字串讓我們判別。將來如果有使用者回報網頁在某些 APP 執行異常時,前端工程師們再想辦法 Google 該內建瀏覽器的偵測字串吧!
更多 Javascript 相關技巧: