【问题标题】:Detecting Custom Protocol Handler in Windows 8+ with Chrome使用 Chrome 在 Windows 8+ 中检测自定义协议处理程序
【发布时间】:2015-05-20 10:16:18
【问题描述】:

我正在尝试检测我处理自定义协议的应用程序是否已安装并使用不同的浏览器工作。我查看了该网站上的其他问题,例如: How to detect browser's protocol handlers?, 并查看了类似的资源,使其能够在大多数浏览器的大多数平台上运行。

在将其标记为重复之前,请听我说...

我能够让我的功能在 Windows 8+ 上除 Chrome 之外的所有设备上运行。我不能像在 Windows 7 上那样在 Chrome 上使用窗口焦点方法,因为它会弹出一条消息,要求我在商店中查找应用程序。

是否有任何方法(缺少扩展)来检测 Chrome 上 Windows 8+ 中的自定义协议处理程序?

更新:

使用 onBlur 检测它仅适用于 Windows 7,因为在 8+ 中,如果它没有找到可以打开您的协议的内容,它会打开“从应用商店查找内容”对话框,使浏览器失去焦点.

【问题讨论】:

  • windows上的chrome很重要,你需要检测哪个prototcol?
  • @dandavis 我同意。这是一个自定义协议...例如“foo://”
  • @dandavis 它没有 mime 类型。就名字而言,它可以是我想要的任何东西。
  • 您可能能够从弹出窗口的行为中嗅出副作用,例如它是否立即关闭或停留在谷歌插件上(我不知道,这听起来很合理)
  • 你希望它做什么?忽略你的协议?请澄清问题和预期的解决方案。

标签: javascript google-chrome windows-8 protocols custom-protocol


【解决方案1】:

嘿,我认为你是在正确的轨道上。这绝对不是那么容易,但到目前为止 chrome 还不是我的问题,更像是 Edge + IE,但我的解决方案是假设它们不支持协议,如果出现任何故障或者它们有时无法正确响应。

模糊/焦点需要检查,但您需要结合可见性更改进行检查。 HTML5 Visiblity API 和这篇文章 about it 帮助我找到了一个非常可靠的解决方案,除了上面提到的浏览器,因为它们在 navigator.msLaunchUri 函数方面存在一些问题,并且实现了自己的方法不依赖模糊/聚焦。但是该功能有问题,并且始终无法正确响应。

你可以找到我的密码笔here。希望这对您有所帮助,即使答案有点晚了。这也适用于移动浏览器,但我没有测试多个还适用于我的 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】:

    我认为这可能会帮助您 here 使用不同的浏览器,但请更好地定义您的问题或添加至少一些示例以使其清楚。

    【讨论】:

    • 我看过这样的解决方案。问题是 Chrome 解决方案仅适用于 Windows 7。我不太明白我的问题是如何不清楚的......
    • 嗨 PixelAcorn,我在 Chrome 上遇到了同样的问题,正在等待您的反馈
    猜你喜欢
    • 2021-02-15
    • 2011-10-28
    • 1970-01-01
    • 2015-11-10
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多