瀏覽器中喚起 native app或者跳轉到下載頁面

導語   在做 h5 頁面中,會遇到這樣一個需求,有一個立即打開的按鈕,如果本地安裝了我們的 app,那么點擊就直接喚起本地 app,如果沒有安裝,則跳轉到下載。  首先想到的是兩個問題:一是如何喚起本地 app,

  在做 h5 頁面中,會遇到這樣一個需求,有一個立即打開的按鈕,如果本地安裝了我們的 app,那么點擊就直接喚起本地 app,如果沒有安裝,則跳轉到下載。

  首先想到的是兩個問題:一是如何喚起本地 app,二是如何判斷瀏覽器是否安裝了對應 app。

  如何喚起本地 app

  首先,想要實現這個需求,肯定是必須要客戶端同學的配合才行,因此我們不用知道所有的實現細節,我們從前端角度思考看這個問題,需要知道的一點是,ios 與 Android 都支持一種叫做 schema 協議的鏈接。比如網易新聞客戶端的協議為

  JavaScript

  1. newsapp://xxxxx 

  當然,這個協議不需要我們前端去實現,我們只需要將協議放在 a 標簽的 href 屬性里,或者使用 location.href 與 iframe 來實現激活這個鏈接。而 location.href 與 iframe 是解決這個需求的關鍵。

  在 ios 中,還支持通過smart app banner來喚起 app,即通過一個 meta 標簽,在標簽里帶上 app 的信息,和打開后的行為,代碼形如

  XHTML

  1. <meta name="apple-itunes-app" content="app-id=1023600494, app-argument=tigerbrokersusstock://com.tigerbrokers.usstock/post?postId=7125" /> 

  需要注意的是:我們就沒辦法通過這個協議在微信中直接喚起 app。原因是微信里屏蔽了 schema 協議,除非你是微信的合作伙伴之類的,他們專門給你配置進白名單。

  因此我們會判斷頁面場景是否在微信中,如果在微信中,則會提示用戶在瀏覽器中打開。

  如何判斷本地是否安裝了 app

  首先我們可以確認的是,在瀏覽器中無法明確的判斷本地是否安裝了 app。因此我們必須采取一些取巧的思路來解決這個問題。

  我們能夠很容易想到,采用設置一個延遲定時器 setTimeout 的方式,第一時間嘗試喚起 app,如果 200ms 沒有喚起成功,則默認本地沒有安裝 app,200ms 以后,將會觸發下載行為。

  結合這個思路,我們來全局考慮一下這個需求應該采用什么樣的方案來實現它。

  使用 location.href 的同學可能會面臨一個擔憂,在有的瀏覽器中,當我們嘗試激活 schema link 的時候,若本地沒有安裝 app,則會跳轉到一個瀏覽器默認的錯誤頁面去了。因此大多數人采用的解決方案都是使用 iframe

  測試了很多瀏覽器,沒有發現過這種情況

  后來觀察了網易新聞,今日頭條,YY 等的實現方案,發現大家都采用的是 iframe 來實現。好吧,面對這種情況,只能屈服。

  整理一下目前的思路,得到下面的解決方案

  JavaScript

  1. var url = { 
  2.  
  3.   open: 'app://xxxxx'
  4.  
  5.   down: 'xxxxxxxx' 
  6.  
  7.   }; 
  8.  
  9.   var iframe = document.createElement('iframe'); 
  10.  
  11.   var body = document.body; 
  12.  
  13.   iframe.style.cssText='display:none;width=0;height=0'
  14.  
  15.   var timer = null
  16.  
  17.   // 立即打開的按鈕 
  18.  
  19.   var openapp = document.getElementById('openapp'); 
  20.  
  21.   openapp.addEventListener('click'function() { 
  22.  
  23.   if(/MicroMessenger/gi.test(navigator.userAgent) { 
  24.  
  25.   // 引導用戶在瀏覽器中打開 
  26.  
  27.   }) else
  28.  
  29.   body.appendChild(iframe); 
  30.  
  31.   iframe.src = url.open; 
  32.  
  33.   timer = setTimeout(function() { 
  34.  
  35.   wondow.location.href = url.down; 
  36.  
  37.   }, 500); 
  38.  
  39.   } 
  40.  
  41.   }, false

  想法很美好,現實很殘酷。一測試,就發現簡單的這樣實現有許多的問題。

  第一個問題在于,當頁面成功喚起 app 之后,我們再切換回來瀏覽器,發現跳轉到了下載頁面。

  為了解決這個問題,發現各個公司都進行了不同方式的嘗試。

  也是歷經的很多折磨,發現了幾個比較有用的事件。

  pageshow 頁面顯示時觸發,在 load 事件之后觸發。需要將該事件綁定到 window 上才會觸發

  pagehide 頁面隱藏時觸發

  visibilitychange 頁面隱藏沒有在當前顯示時觸發,比如切換 tab,也會觸發該事件

  document.hidden 當頁面隱藏時,該值為 true,顯示時為 false

  由于各個瀏覽器的支持情況不同,我們需要將這些事件都給綁定上,即使這樣,也不一定能夠保證所有的瀏覽器都能夠解決掉這個小問題,實在沒辦法的事情就不管了。

  因此需要擴充一下上面的方案,當本地 app 被喚起,則頁面會隱藏掉,就會觸發 pagehide 與 visibilitychange 事件

  JavaScript

  1. $(document).on('visibilitychange webkitvisibilitychange'function() { 
  2.  
  3.   var tag = document.hidden || document.webkitHidden; 
  4.  
  5.   if (tag) { 
  6.  
  7.   clearTimeout(timer); 
  8.  
  9.   } 
  10.  
  11.   }) 
  12.  
  13.   $(window).on('pagehide'function() { 
  14.  
  15.   clearTimeout(timer); 
  16.  
  17.   }) 

  而另外一個問題就是 IOS9+ 下面的問題了。ios9 的 Safari,根本不支持通過 iframe 跳轉到其他頁面去。也就是說,在 safari 下,我的整體方案被全盤否決!

  于是我就只能嘗試使用 location.href 的方式,這個方式能夠喚起 app,但是有一個坑爹的問題,使用 schema 協議喚起 app 會有彈窗而不會直接跳轉去 app!甚至當本地沒有 app 時,會被判斷為鏈接無效,然后還有一個彈窗。

  這個彈窗會造成什么問題呢?如果用戶不點確認按鈕,根據上面的邏輯,這個時候就會發現頁面會自動跳轉到下載去了。而且無效的彈窗提示在用戶體驗上是不允許出現的。

  好吧,繼續扒別人的代碼,看看別人是如何實現的。然后我又去觀摩了其他公司的實現結果,發現網易新聞,今日頭條都可以在 ios 直接從微信中喚起 app。真是神奇了,可是今日頭條在 Android 版微信上也沒辦法直接喚起的,他們在 Android 上都是直接到騰訊應用寶的下載里去。所以按道理來說這不是添加了白名單。

  為了找到這個問題的解決方案,我在網易新聞的頁面中扒出了他們的代碼,并整理如下,添加了部分注釋(因涉及的代碼塊篇幅過長,考慮到閱讀效果,請至閱讀原文查看。

  雖然有一些外部的引用,和一些搞不懂是干什么用的方法和變量,但是基本邏輯還是能夠看明白。好像也沒有什么特別的地方。研究了許久,看到了一個 jsonp 請求很奇特。這是來干嘛用的?

  于是費盡千辛萬苦,搜索了很多文章,最終鎖定了一個關鍵的名詞 Universal links。

  如果我早知道這個名詞,那么問題就不會變的那么束手無策。所以這個東西是什么呢?

  Apple 為 iOS 9 發布了一個所謂的通用鏈接的深層鏈接特性,即 Universal links。雖然它并不完美,但是這一發布,讓數以千計的應用開發人員突然意識到自己的應用體驗被打破。

  Universal links,一種能夠方便的通過傳統的 HTTP/HTTPS 鏈接來啟動 App,使用相同的網址打開網站和 App。

  關于這個問題的提問與 universal links 的介紹請至閱讀原文

  ios9 推行的一個新的協議!

  關于本文的這個問題,國內的論壇有許許多多的文章來解決,但是提到 universal links 的文章少之又少,而我想吐槽的是,我們的 ios 開發也尼瑪不知道這個名詞,搞什么鬼。他改變了用戶體驗的關鍵在于,微信沒有屏蔽這個協議。因此如果我們的 app 注冊了這個協議,那么我們就能夠從微信中直接喚起 app。

  這個時候我就發現,上面貼的網易新聞代碼中的 jsonp 請求的內容,就是這個協議必須的一個叫做apple-app-site-association的 JSON 文件

  JavaScript

  1.  
  2.   "applinks": { 
  3.  
  4.   "apps": [ ], 
  5.  
  6.   "details": { 
  7.  
  8.   "TEAM-IDENTIFIER.YOUR.BUNDLE.IDENTIFIER": { 
  9.  
  10.   "paths": [ 
  11.  
  12.   "*" 
  13.  
  14.   ] 
  15.  
  16.   } 
  17.  
  18.   } 
  19.  
  20.   } 
  21.  
  22.   } 

  大家可以直接訪問這個鏈接,查看里面的內容

  http://active.163.com/service/form/v1/5847/view/1047.jsonp

  至于 universal links 具體如何實現,讓 ios 的同學去搞定吧,這里提供兩個參考文章

  http://www.cocoachina.com/bbs/read.php?tid-1486368.html

  https://blog.branch.io/how-to-setup-universal-links-to-deep-link-on-apple-ios-9

  支持了這個協議之后,我們又可以通過 iframe 來喚起 app 了,因此基本邏輯就是這樣了。最終的調研結果是

  沒有完美的解決方案

  就算是網易新聞,這個按鈕在使用過程中也會有一些小 bug,無法做到完美的狀態。

  因為我們面臨許多沒辦法解決的問題,比如無法真正意義上的判斷本地是否安裝了 app,pageshow,pagehide 并不是所有的瀏覽器都支持等。很多其他博客里面,什么計算時間差等方案,根!本!沒!有!用!我還花了很久的時間去研究這個方案。

  老實說,從微信中跳轉到外部瀏覽器,并不是一個好的解決方案,這樣會導致很多用戶流失,因此大家都在 ios 上實現了 universal links,而我更加傾向的方案是知乎的解決,他們從設計上避免了在一個按鈕上來判斷這個邏輯,而采用了兩個按鈕的方式。

  網易新聞的邏輯是,點擊打開會調整到一個下載頁面,這個下載頁面一加載完成就嘗試打開app,如果打開了就直接跑到 app 里面去了,如果沒有就在頁面上有一個立即下載的按鈕,按鈕行只有下載處理。

http://www.huibzy.icu/ true 瀏覽器中喚起 native app或者跳轉到下載頁面 http://www.huibzy.icu/show-24-877-1.html report 6738   在做 h5 頁面中,會遇到這樣一個需求,有一個立即打開的按鈕,如果本地安裝了我們的 app,那么點擊就直接喚起本地 app,如果沒有安裝,則跳轉到下載。  首先想到的是兩個問題:一是如何喚起本地 app,
TAG:瀏覽器 native app
本站歡迎任何形式的轉載,但請務必注明出處,尊重他人勞動成果
轉載請注明: 文章轉載自:愛思資源網 http://www.huibzy.icu/show-24-877-1.html

[前端插件推薦] Plugin

1 2 3 4
  • jQuery實現逐字逐句顯示插件l-by-l.min.js
  • jQuery帶方向感知的鼠標滑過圖片邊框特效插件
  • jQuery HotKeys監聽鍵盤按下事件keydown插件
  • 響應式無限輪播jQuery旋轉木馬插件
響應式無限輪播jQuery旋轉木馬插件
web前端開發
愛思資源網 Copyright 2012-2014 www.huibzy.icu All rights reserved.(晉ICP備13001436號-1)
棋牌游戏推广招代理