[貝聊科技]網頁端「應用跳轉」技術實現演變

貝聊科技發表於2018-01-22

本文作者:Mr.Luo ,貝聊前端經理。本文同時釋出於作者 個人部落格

由於網頁傳播的便捷性,從網頁向APP導流幾乎是所有APP廠商都會採用的推廣手段,具體來說就是在網頁上提供一些觸發點(例如按鈕、連結),用於跳轉到APP。

應用跳轉

01.URL Scheme

早期的應用跳轉只能通過「URL Scheme」實現。例如通過下面這個「URL Scheme」,就可以跳轉到「貝聊APP」:

ibeiliao://

在網頁中呼叫「URL Scheme」也有多種方法:

<!-- 方案一:連結跳轉 -->
<a href="ibeiliao://">開啟貝聊</a>

<!-- 方案二:JS跳轉 -->
<a href="javascript:location.href='ibeiliao://'">開啟貝聊</a>

<!-- 方案三:iframe呼叫 -->
<span id="open-ibeiliao">開啟貝聊</span>
<script>
document.getElementById('open-ibeiliao').onclick = function() {
    var iframe = document.createElement('iframe');
    iframe.src = 'ibeiliao://';
    iframe.style.display = 'none';
    document.body.appendChild(iframe);
    setTimeout(function(){
        document.body.removeChild(iframe);
    }, 3000);
};
</script>
複製程式碼

原本「方案三」是最受歡迎的,因為在沒有安裝對應APP的情況下,另外兩個方案在iOS Safari下都會出現「瀏覽器無法開啟網頁」的彈框。

沒有安裝APP時的彈框

然而,「方案三」是最先“陣亡”的,最早是在iOS 9中的Safari失效,後來在某些安卓機的瀏覽器也不行了,所以目前只能用「方案一」和「方案二」,而iOS Safari下的那個彈框也就無法避免了。

理論上,「URL Scheme」可以在任何瀏覽器以及APP中的WebView使用,但實際上卻是被大量APP封殺,幾乎是只能在瀏覽器類的APP中使用。因為大部分廠商都不希望使用者離開自己的APP。

02.開啟還是下載?

前文提到了一個問題,萬一裝置上沒有安裝要跳轉的APP,那怎麼辦呢?正常來說,應該要跳到該APP的下載頁。然而,這裡面最大的難題是:網頁端基本上無法獲知當前裝置是否已安裝某個APP(之所以加上“基本”二字,是因為網頁在微信內執行時,可通過呼叫微信內部的JS API實現此功能,但該API只對騰訊的“關係戶”開放)。

後來,人們想出了一種解決方案:在使用「URL Scheme」跳轉的同時,通過定時器在一定時間之後跳轉到下載頁。倘若裝置上有安裝APP,就會跳到APP,否則在一定時間後就會跳到下載頁。

<span id="open-ibeiliao">開啟貝聊</span>
<script>
document.getElementById('open-ibeiliao').onclick = function() {
    window.location.href = 'ibeiliao://';
    setTimeout(function() {
        window.location.href = 'https://mobile.ibeiliao.com/download';
    }, 1000);
};
</script>
複製程式碼

這麼做基本上是達到了目的,但是有兩處體驗問題仍然無法解決:

  • 即便已經安裝APP,瀏覽器也會跳到下載頁。使用者從APP返回瀏覽器時會發現莫名其妙地出現了下載頁。
  • 在沒有安裝APP的情況下,iOS Safari的彈框還是無法避免,但是跳到下載頁之後會消失。

03.應對封殺

前文有提及,「URL Scheme」被大量APP封殺,其中就包括常用的QQ和微信,但是沒有誰會放棄這兩個重要渠道,所以還是得想轍。

最無奈的解決方案就是提示使用者「用瀏覽器開啟網頁」,繼而讓使用者在瀏覽器中開啟APP。然而,這對非IT人士來說,操作起來還是有一點繁雜的。

提示使用者用瀏覽器開啟

另一種好一點的做法是,先跳轉到騰訊的「應用寶」,「應用寶」會根據裝置是否已裝APP去執行開啟或者下載操作。當然,這種做法需要把APP傳到「應用寶」,而且只對騰訊系的APP有效;對於其他APP,仍然只能提示「用瀏覽器開啟網頁」。

應用寶

最後一個解決方案就是下文要講述的「Universal Links」。

04.Universal Links

「Universal links」,中文翻譯為「通用連結」,從iOS 9開始支援,僅通過普通的https請求就能跳轉到指定的應用。

開發者可以把應用的下載頁地址配置為一條通用連結,這樣,使用者在進入下載頁時:

  • 如果裝置上已安裝APP,則進入APP;
  • 如果裝置上沒有安裝APP,則進入下載頁,再也沒有那個煩人的彈框了。

最重要的是,通過「通用連結」,即使在微信、QQ內,也能如絲般順滑地跳到自家APP。大家都以為這是系統級別的處理,無法被任何APP封殺,直到不久前的一天,它在微信下跪了。。。根據某大神的分析,蘋果還是給「通用連結」留下了“後門”可以讓其失效。

而在Android系統下,也有類似的技術,即App Links,從Android M開始支援。但由於國內安卓版本碎片化比較嚴重,所以應用還不怎麼廣泛。

05.小結

講到這,先小結一下應用跳轉的實現方案。

  • Android:
    • 微信、QQ:「URL Scheme」不可用,可通過「應用寶」中轉。
    • 瀏覽器:「URL Scheme」可用。
    • 其他APP:提示用瀏覽器開啟。
  • iOS>=9(支援「Universal Links」):
    • 微信:「URL Scheme」和「Universal Links」均不可用,通過「應用寶」中轉。
    • QQ:「Universal Links」尚且可用。
    • QQ瀏覽器:「Universal Links」不可用,但「URL Scheme」可用。
    • 其他APP:「Universal Links」可用。
  • iOS<9(不支援「Universal Links」):
    • 微信、QQ:「URL Scheme」不可用,提示用瀏覽器開啟。
    • 各瀏覽器:「URL Scheme」可用。
    • 其他APP:提示用瀏覽器開啟。

要注意的是,所謂的「其他APP」是無法準確檢測的,只能根據APP在User Agent中增加的特殊關鍵字(例如新浪微博的「Weibo」)逐個判斷。

06.開啟APP的指定頁

需求是無止境的,能從網頁進入APP只是開始,下一步就是跳轉到指定頁面。這裡所說的指定頁面,可能是原生的頁面,也可能是某個網頁。這個過程的關鍵在於開啟APP時如何把頁面路徑傳過去。

先從「URL Scheme」說起。我們可以給「URL Scheme」加上路徑和引數,例如:

my-app://open?url=https%3A%2F%2Fcn.bing.com%2F

APP端只要解析引數,繼而開啟對應的頁面即可。對於「Universal Links」來說,也是同理:

my-app.com/download?ur…

正如上文所說,「URL Scheme」和「Universal Links」都被微信封殺了。如果通過「應用寶」中轉,上述url引數是無法傳到APP的。在這種情況下,就得尋找一個微信WebView和APP都可以共同讀寫的空間來傳遞資料,例如剪貼簿。下面這個JS函式可以實現對剪貼簿的寫入:

function copyToClipboard(content) {
    var textarea = document.createElement('textarea');
    textarea.style.position = 'absolute';
    textarea.style.left = '-1000px';
    textarea.style.top = '-1000px';
    textarea.value = content;
    textarea.readOnly = true;
    document.body.appendChild(textarea);

    textarea.select();
    textarea.setSelectionRange(0, textarea.value.length);

    var result = false;
    try {
        result = document.execCommand('copy');
    } catch (e) {

    }

    document.body.removeChild(textarea);
    textarea = null;

    return result;
}
複製程式碼

跳轉到APP的應用寶地址之前,把要開啟的頁面地址以約定好的格式寫入剪貼簿:

copyToClipboard('my-app:open?url=https%3A%2F%2Fcn.bing.com%2F');
location.href = 'my-app的應用寶地址';
複製程式碼

通過「應用寶」開啟APP後,APP端按照約定格式解析剪貼簿內容開啟對應的頁面即可。

這裡有一個細節:為什麼不直接以完整的「my-app://open?url=」寫入剪貼簿,而要特意去掉「//」?這是因為在Android系統下,某些瀏覽器APP會把剪貼簿中的「URL Scheme」識別為網址,然後提示使用者是否開啟。對於使用者來說,點選「開啟APP」出現這個提示,就有點莫名其妙了。

當然,「剪貼簿方案」也存在一些問題:

  • 會覆蓋使用者的剪貼簿內容。
  • 部分Android系統的原生瀏覽器不支援通過JS訪問剪貼簿,不過這不是問題,因為在瀏覽器中大可以用「URL Scheme」。

如果不想用「剪貼簿方案」,還是可以提示使用者用瀏覽器開啟頁面的。具體如何取捨,就看各自產品經理的決定了。

相關文章