美文网首页
PC调起客户端

PC调起客户端

作者: 我才是大田田 | 来源:发表于2019-01-02 16:44 被阅读0次

最近遇到的需求是:pc点击按钮,如果装了客户端,就打开客户端;如果没装客户端,跳转到pc下载客户端页面。
这个思路和之前h5打开app类似,不过比那个简单。

方案是:尝试打开客户端,设置定时器跳转下载页。若打开,则清除定时器。

直接上代码

// 调起客户端
export const launchCustomProtocol = (uri) => {
  // 注册事件
   function _registerEvent(target, eventType, cb) {
       if (target.addEventListener) {
           target.addEventListener(eventType, cb);
           return {
               remove: function () {
                   target.removeEventListener(eventType, cb);
               }
           };
       } else {
           target.attachEvent(eventType, cb);
           return {
               remove: function () {
                   target.detachEvent(eventType, cb);
               }
           };
       }
   }
 
  // 插入隐藏的iframe
   function _createHiddenIframe(target, uri) {
       var iframe = document.createElement("iframe");
       iframe.src = uri;
       iframe.id = "hiddenIframe";
       iframe.style.display = "none";
       target.appendChild(iframe);

       return iframe;
   }

  // 利用window的blur事件清除callback
function openUriWithHiddenFrame(uri, failCb) {

       var timeout = setTimeout(function () {
           failCb();
           handler.remove();
       }, 1000);

       var iframe = document.querySelector("#hiddenIframe");
       if (!iframe) {
           iframe = _createHiddenIframe(document.body, "about:blank");
       }

       var handler = _registerEvent(window, "blur", onBlur);

       function onBlur() {
           clearTimeout(timeout);
           handler.remove();
       }

       iframe.contentWindow.location.href = uri;
   }

// 利用超时的hack方案清除callback
function openUriWithTimeoutHack(uri, failCb, successCb) {

       var timeout = setTimeout(function () {
           failCb();
           handler.remove();
       }, 1000);
       //handle page running in an iframe (blur must be registered with top level window)
           var target = window;
           while (target != target.parent) {
               target = target.parent;
           }

           var handler = _registerEvent(target, "blur", onBlur);

           function onBlur() {
               clearTimeout(timeout);
               handler.remove();
               successCb();
           }

           window.location = uri;
   }

// firefox兼容
function openUriUsingFirefox(uri, failCb, successCb) {
       var iframe = document.querySelector("#hiddenIframe");

       if (!iframe) {
       iframe = _createHiddenIframe(document.body, "about:blank");
       }

       try {
       iframe.contentWindow.location.href = uri;
       successCb();
       } catch (e) {
       if (e.name == "NS_ERROR_UNKNOWN_PROTOCOL") {
           alert("Un Kown!")
           failCb();
       }
       }
   }

// 兼容ie,利用ie的MsLaunch
function openUriWithMsLaunchUri(uri, failCb, successCb) {
       navigator.msLaunchUri(uri,
           successCb,
           failCb
           );
   }

// 判断浏览器类型
   function checkBrowser() {
       var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
       return {
       isOpera   : isOpera,
       isFirefox : typeof InstallTrigger !== 'undefined',
       isSafari  :/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent),
       // isSafari  : Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0,
       isChrome  : !!window.chrome && !isOpera
       }
   }


设置打开客户端失败的回调函数
   function failCallback() {
       window.location.href = location.origin + '/download'
   }
let supported = true
   if (navigator.msLaunchUri) { //for IE and Edge in Win 8 and Win 10
       openUriWithMsLaunchUri(uri, failCallback);
   } else {
       var browser = checkBrowser();
       console.log('browser', browser)
       if (browser.isFirefox) {
           openUriUsingFirefox(uri, failCallback);
       } else if (browser.isChrome) {  //  
           openUriWithTimeoutHack(uri, failCallback);
       } else if (browser.isSafari) {
           openUriWithHiddenFrame(uri, failCallback)    
       } else {
           supported = false
           return supported
       }
   }
}

测试该方案兼容以下浏览器:

Qq桌面浏览器  
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6721.400 QQBrowser/10.2.2243.400

chrome               
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36

360极速              
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36

360安全              
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36

safari                  
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.1 Safari/605.1.15

搜狗                    
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0

2345                 
Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; .NET4.0C; .NET4.0E; Tablet PC 2.0; rv:11.0) like Gecko
Copy

参考

Native-App-Protocal-Detection
How to detect browser's protocol handlers?
How to check if a custom protocol supported
custom-protocol-detection
AboutAsynchronousPluggableProtocols

相关文章

网友评论

      本文标题:PC调起客户端

      本文链接:https://www.haomeiwen.com/subject/dijycqtx.html