Подтвердить что ты не робот

Обнаружение обработчика пользовательских протоколов в Windows 8+ с Chrome

Я пытаюсь определить, установлено ли мое приложение для обработки настраиваемого протокола и работает с использованием разных браузеров. Я рассмотрел другие вопросы на этом сайте, такие как: Как определить обработчики протоколов браузера?, и рассмотрели такие ресурсы, чтобы они работали на большинстве платформ в большинстве браузеров.

Прежде чем вы будете отмечать это как дубликат, выслушайте меня...

Мне удалось заставить мою функцию работать над всем, кроме Chrome в Windows 8+. Я не могу использовать метод фокуса окна в Chrome, как я могу, в Windows 7, потому что он выводит сообщение, которое просит меня найти приложение в магазине.

Есть ли способ (не до конца) для обнаружения пользовательского обработчика протокола в Windows 8+ в Chrome?

UPDATE:

Использование onBlur для его обнаружения работает только в Windows 7, потому что в 8+, если он не находит что-то, чтобы открыть ваш протокол, он открывает диалоговое окно "найти что-то из магазина приложений", которое заставляет браузер терять фокус,

4b9b3361

Ответ 1

Эй, я думаю, ты был на правильном пути. Это определенно не так просто, но хром пока не был моей проблемой, больше похожей на Edge + IE, но мое решение предполагает, что они не поддерживают протокол, если что-то не работает или они не отвечают правильно, что они иногда делают.

Размытие/фокус - это что-то проверить, но вам нужно проверить его в сочетании с изменением видимости. API HTML Visiblity и этот пост об этом помогли мне найти решение, которое довольно твердое, за исключением упомянутых выше браузеров, потому что у них есть некоторые проблемы с функцию navigator.msLaunchUri и реализовать свой собственный подход, который не полагается на размытие/фокус. Но функция прослушивается и не реагирует правильно все время.

Здесь вы можете найти мой код здесь. Надеюсь, это поможет вам, хотя немного опоздал на ответ. Это работает и для мобильных браузеров, но я не тестировал несколько, но работал на моем Android 6.0.2. Может потребоваться некоторые изменения в долгосрочной перспективе, но я думаю, что это довольно солидно.

(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();
});

Мой код протестирован с помощью Win10: Chrome, Firefox, IE11, Edge + Android: Chrome (6.0.1)

существует также этот проект github https://github.com/ismailhabib/custom-protocol-detection, который имеет аналогичный подход, возможно, немного более поддерживается, но я не мог получить их решение работает по некоторым причинам, но, возможно, это именно то, что вам нужно.

Ответ 2

Я думаю, что это может помочь вам здесь с разными браузерами, но, пожалуйста, задайте вопрос лучше или добавьте хотя бы какой-то пример, чтобы он дал понять.