Detecting Custom Protocol Handler in Windows 8+ with Chrome

南楼画角 提交于 2019-12-03 10:50:20

问题


I am trying to detect if my application to handle a custom protocol is installed and working using the different browsers. I have looked at other questions on this site such as: How to detect browser's protocol handlers?, and have looked at resources like this to make it work on most platforms in most browsers.

Before you flag this as duplicate, hear me out...

I was able to get my function working on everything except Chrome on Windows 8+. I cannot use the window focus method on Chrome like I can on Windows 7 because it pops up the message that asks me to find an app in the store.

Is there any way (short of an extension) to detect a custom protocol handler in Windows 8+ on Chrome?

UPDATE:

Using an onBlur to detect it only works on Windows 7, because in 8+, if it doesn't find something to open your protocol, it opens the 'find something from the app store' dialog that makes the browser lose focus.


回答1:


Hey I think you were on the right track. It is definitly not that easy but chrome so far was not my problem, more like Edge + IE but my solution is assuming they don't support the protocol if anything fails or they don't respond correctly which they do sometimes.

The blur/focus is something to check but you need to check it in combination with a visibility change. The HTML5 Visiblity API and this post about it helped me figure out a solution that is pretty solid except the mentioned browsers above because they have some issues with the navigator.msLaunchUri function and have their own approach implemented which doesn't rely on blur/focus. But the function is bugged and doesn't respond correctly all the time.

You can find my codepen here. Hopefully that helps you even though it is a bit late for an answer. This works for mobile browsers as well but I didn't test multiple yet worked for my Android 6.0.2. Might need some tweaks in the long run but I think it is pretty solid.

(function() {
  var noProtocolHash = '#protocolXYnotsupported',
      checkDelay = 800, // apps might start slowly
      isBlurred = false,
      inCheck = false,
      inLauncherCheck = false,

  tabVisible = (function(){ 
      var stateKey, 
          eventKey, 
          keys = {
                  hidden: "visibilitychange",
                  webkitHidden: "webkitvisibilitychange",
                  mozHidden: "mozvisibilitychange",
                  msHidden: "msvisibilitychange"
      };
      for (stateKey in keys) {
          if (stateKey in document) {
              eventKey = keys[stateKey];
              break;
          }
      }
      return function(c) {
          if (c) document.addEventListener(eventKey, c);
          return !document[stateKey];
      }
  })(),

  isMSIE = function(){
    var rv = -1;

    if(navigator.appName == 'Microsoft Internet Explorer'){
      var ua = navigator.userAgent;
      var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
      if(re.exec(ua) != null){
        rv = parseFloat(RegExp.$1);
      }
    }
    else if(navigator.appName == 'Netscape'){
      var ua = navigator.userAgent;
      var re  = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
      if(re.exec(ua) != null){
        rv = parseFloat(RegExp.$1);
      }
    }
    return (rv !== -1)? true: false;
  },

  isEdge = function(){
    return window.navigator.userAgent.indexOf("Edge") > -1;
  },

  checkIfFocusLost = function($el){
    try {
      document.location.href = $el.attr("href");
    } catch (ex) {
        document.location.href = document.location.href + '/' + noProtocolHash;
    }

    setTimeout(checkVisibility, checkDelay);
  },

  checkVisibility = function(){
    if(tabVisible() && !isBlurred){
      handleNoProtocol();
    }
    else {
      handleProtocol();
    }
  },

  handleNoProtocol = function(){
    $('.result').text('has no protocol');

    inLauncherCheck = false;
  },

  handleProtocol = function(){
    $('.result').text('has the protocol');

    inLauncherCheck = false;
  },

  checkHash = function(){
    if(document.location.hash === noProtocolHash){
      handleNoProtocol();
    }
  },

  checkLauncherProtocol = function($el){
    inLauncherCheck = true;

    navigator.msLaunchUri($el.attr("href"), function(){
      handleProtocol();
    }, 
    function(){
      handleNoProtocol();
    });

    setTimeout(function(){
      // fallback when edge is not responding correctly
      if(inLauncherCheck === true){
        handleNoProtocol();
      }
    }, 500);
  },

  checkIfHasProtocol = function($el){
    inCheck = true;

    if(isEdge() || isMSIE()){
      checkLauncherProtocol($el);
    }
    else {
      checkIfFocusLost($el)
    }
  };

  checkHash();
  tabVisible(function(){
    if(tabVisible() && inCheck){
      handleProtocol();
      inCheck = false;
    }    
  });

  window.addEventListener("blur", function(){
    isBlurred = true;   
  });

  window.addEventListener("focus", function(){
    isBlurred = false; 
    inCheck = false;
  });

  window.checkIfHasProtocol = checkIfHasProtocol;
})();

$('.protocol').click(function(e) {
  checkIfHasProtocol($(this));
  e.preventDefault();
});

My code is tested with Win10: Chrome, Firefox, IE11, Edge + Android: Chrome (6.0.1)

there is also this github project https://github.com/ismailhabib/custom-protocol-detection which sorta has a similar approach maybe a little bit more maintained but i couldn't get their solution working for some reasons but maybe this is exactly what you need.




回答2:


I think this might help you here with different browsers, but please define you question better or add at least some kinda example to make it clear.



来源:https://stackoverflow.com/questions/29108347/detecting-custom-protocol-handler-in-windows-8-with-chrome

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!