在H5頁面或者app的webview中調起第三方app前端
調起app是操做系統(iOS、Android)的機制,在h5頁面,咱們能夠作的很少。android
在調起以前,h5頁面沒法判斷當前手機是否安裝了對應的app,咱們只能去嘗試調起,而且用一些方法來處理沒有調起的狀況。web
調起的原理就不介紹了,網上一搜一大堆。直接上核心代碼。chrome
if(iOS9) { window.location.href = ${universalLink}; } else { var ifr = document.createElement('iframe'); ifr.src = ${scheme}; ifr.style.display = 'none'; document.body.appendChild(ifr); window.setTimeout(function () { document.body.removeChild(ifr); }, 300); } 舉個栗子: ${universalLink} = 'http://myapp.com' ${scheme} = 'myapp://index'
解釋一下上面的代碼,若是是iOS9及以上的iOS系統,直接跳轉到調起app的universal link。若是是安卓或者iOS9一下的iOS系統,就新建一個iframe,把這個iframe的src弄成調起app的scheme,而後把這個iframe直接塞到頁面的DOM樹上,而後『聽天由命』就行。後端
iOS是使用universalLink(下面簡稱ulink)的方式來進行調起。具體系統內部的機制就不說了,網上一堆文章,隨便搜一下就行。瀏覽器
universalLink其實就是一個正常的http請求的url。咱們在h5頁面使用 location.href=XX進行調起的時候,若是說調起成功了,那麼其實這個url是不會被訪問的,抓包也抓不到。換句話說,若是咱們訪問到這個url了,說明咱們的調起失敗了。微信
上面說了,iOS下調起失敗後,會訪問到一個url。要實現沒有安轉跳下載頁,那麼就直接把ulink對應的連接作成下載頁就行了。根據需求,咱們還能夠將ulink對應的url作成任何頁面。可是,若是咱們不想要跳轉到這個頁面,仍是想停留在以前的頁面呢?很簡單,叫RD哥哥在通鏈那個url的服務端加一個302重定向服務就行。app
舉個栗子,咱們使用下面的ulink來調起App。jsp
http://myapp.com/index?target=encodeURIComponent('http://www.baidu.com');
url
調起失敗後,上面那個ulink會被瀏覽器訪問到,咱們在服務端加了重定向服務,咱們最終會訪問到target對應的地址,即 http://www.baidu.com 。這樣,咱們就實現了【調起失敗時,跳轉到本身想要的頁面】。
兩種方法:
1、須要後端重定向服務,咱們只須要把上面重定向的連接換成一個scheme就好了。這種方法適用於頁面必需要用戶點擊才能觸發的交互,好比視頻、音頻的播放等。(另:微信下能夠經過監聽jsbridge ready的事件,自動播放視頻、音頻)
這個scheme須要知足如下的要求:
若是這個scheme同時知足了上述兩個條件,那麼體驗就是最好的。不然,可能就會出現瀏覽器彈框等問題。
舉幾個scheme的例子
... facetime:// (iOS11如下體驗完美,以後的版本會直接拉起facetime--) ucbrowser:// ...
2、須要後端重定向服務,咱們須要把重定向連接換成【當前連接後加一個特殊參數】的連接。這樣在前端代碼裏就能夠判斷url裏面的特殊參數,從而得知當前頁面是拉起app失敗時進入的。
安卓的調起是用iframe的方式(其實如今的高版本安卓也能夠直接window.location.href=scheme)。
安卓調起的最大的特色就是,安卓沒法知道是否成功調起了app。安卓下的調起通常都會有自帶的兜底策略,好比下載。代碼也很簡單
var ifr = document.createElement('iframe'); ifr.src = ${scheme}; ifr.style.display = 'none'; document.body.appendChild(ifr); window.setTimeout(function () { document.body.removeChild(ifr); // 這裏寫兜底策略的邏輯,好比下載。 // 固然,也能夠不加任何的兜底策略,調不起就算了。 window.location.href = ${下載地址} }, 300);
若是想要實現【安裝了app調起,沒有安裝app下載】的功能,那麼確定會調起和下載的邏輯同時執行,由於安卓沒法知道是否成功調起app。
安卓的調起是很靈活的,你能夠任意控制兜底策略的邏輯,想幹嗎幹嗎。只是說,兜底策略是幾乎必定會執行的,無論你調起成功仍是失敗。
不少瀏覽器都對scheme作了屏蔽。因此安卓下調不起app是一件十分正常的事情。
微信太封閉了,天然屏蔽了非自家app的調起。只新建一個iframe的方式在微信下是不能調起的。微信針對webview調起app的策略也一直在修改。最新(2018年3月19日)的想要在微信的webview下調起app的方式是:
window.location.href = 'http://a.app.qq.com/o/simple.jsp?pkgname=${pkgname}&android_scheme= encodeURIComponent(${scheme})' ${pkgname}表示app的包名,好比 'com.myapp',${scheme}表示調起的scheme
其實有一種方法能夠判斷安卓下是否調起成功。執行調起邏輯後,設必定的延時判斷當前頁面是否可見,若不可見了,幾乎就能夠肯定是調起成功了。可是隻對小部分瀏覽器有效(好比安卓下的chrome)。對大多數瀏覽器而言,調起成功後,會有一個彈框,須要用戶點擊肯定後,才能喚起app。因爲這個彈框的存在,就沒法經過頁面是否可見的方法來判斷調起成功與否了。而chrome下,調起成功直接喚起app,是不會彈窗的,因此chrome下能夠用延時+頁面是否可見的方式來判斷調起成功與否。
歡迎關注個人公衆號,這裏只有幹活,符合預期