本文做者:Mr.Luo ,貝聊前端經理。本文同時發佈於做者 我的博客 。javascript
因爲網頁傳播的便捷性,從網頁向APP導流幾乎是全部APP廠商都會採用的推廣手段,具體來講就是在網頁上提供一些觸發點(例如按鈕、連接),用於跳轉到APP。html
早期的應用跳轉只能經過「URL Scheme」實現。例如經過下面這個「URL Scheme」,就能夠跳轉到「貝聊APP」:前端
ibeiliao://java
在網頁中調用「URL Scheme」也有多種方法:web
<!-- 方案一:連接跳轉 -->
<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下都會出現「瀏覽器沒法打開網頁」的彈框。瀏覽器
然而,「方案三」是最早「陣亡」的,最先是在iOS 9中的Safari失效,後來在某些安卓機的瀏覽器也不行了,因此目前只能用「方案一」和「方案二」,而iOS Safari下的那個彈框也就沒法避免了。微信
理論上,「URL Scheme」能夠在任何瀏覽器以及APP中的WebView使用,但實際上倒是被大量APP封殺,幾乎是只能在瀏覽器類的APP中使用。由於大部分廠商都不但願用戶離開本身的APP。app
前文提到了一個問題,萬一設備上沒有安裝要跳轉的APP,那怎麼辦呢?正常來講,應該要跳到該APP的下載頁。然而,這裏面最大的難題是:網頁端基本上沒法獲知當前設備是否已安裝某個APP(之因此加上「基本」二字,是由於網頁在微信內運行時,可經過調用微信內部的JS API實現此功能,但該API只對騰訊的「關係戶」開放)。函數
後來,人們想出了一種解決方案:在使用「URL Scheme」跳轉的同時,經過定時器在必定時間以後跳轉到下載頁。假若設備上有安裝APP,就會跳到APP,不然在必定時間後就會跳到下載頁。ui
<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>
複製代碼
這麼作基本上是達到了目的,可是有兩處體驗問題仍然沒法解決:
前文有說起,「URL Scheme」被大量APP封殺,其中就包括經常使用的QQ和微信,可是沒有誰會放棄這兩個重要渠道,因此仍是得想轍。
最無奈的解決方案就是提示用戶「用瀏覽器打開網頁」,繼而讓用戶在瀏覽器中打開APP。然而,這對非IT人士來講,操做起來仍是有一點繁雜的。
另外一種好一點的作法是,先跳轉到騰訊的「應用寶」,「應用寶」會根據設備是否已裝APP去執行打開或者下載操做。固然,這種作法須要把APP傳到「應用寶」,並且只對騰訊系的APP有效;對於其餘APP,仍然只能提示「用瀏覽器打開網頁」。
最後一個解決方案就是下文要講述的「Universal Links」。
「Universal links」,中文翻譯爲「通用連接」,從iOS 9開始支持,僅經過普通的https請求就能跳轉到指定的應用。
開發者能夠把應用的下載頁地址配置爲一條通用連接,這樣,用戶在進入下載頁時:
最重要的是,經過「通用連接」,即便在微信、QQ內,也能如絲般順滑地跳到自家APP。你們都覺得這是系統級別的處理,沒法被任何APP封殺,直到不久前的一天,它在微信下跪了。。。根據某大神的分析,蘋果仍是給「通用連接」留下了「後門」可讓其失效。
而在Android系統下,也有相似的技術,即App Links,從Android M開始支持。但因爲國內安卓版本碎片化比較嚴重,因此應用還不怎麼普遍。
講到這,先小結一下應用跳轉的實現方案。
要注意的是,所謂的「其餘APP」是沒法準確檢測的,只能根據APP在User Agent中增長的特殊關鍵字(例如新浪微博的「Weibo」)逐個判斷。
需求是無止境的,能從網頁進入APP只是開始,下一步就是跳轉到指定頁面。這裏所說的指定頁面,多是原生的頁面,也多是某個網頁。這個過程的關鍵在於打開APP時如何把頁面路徑傳過去。
先從「URL Scheme」提及。咱們能夠給「URL Scheme」加上路徑和參數,例如:
my-app://open?url=https%3A%2F%2Fcn.bing.com%2F
APP端只要解析參數,繼而打開對應的頁面便可。對於「Universal Links」來講,也是同理:
正如上文所說,「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」出現這個提示,就有點莫名其妙了。
固然,「剪貼板方案」也存在一些問題:
若是不想用「剪貼板方案」,仍是能夠提示用戶用瀏覽器打開頁面的。具體如何取捨,就看各自產品經理的決定了。