【问题标题】:Check if URL scheme is supported in javascript检查 javascript 中是否支持 URL 方案
【发布时间】:2010-10-12 06:59:39
【问题描述】:

有什么方法可以检查当前是否在手机上注册了一个 URL 方案...使用 javascript?

【问题讨论】:

标签: javascript iphone safari url-scheme


【解决方案1】:

不是无缝的。 但是有一种方法类似于检查弹出窗口是否被阻止。

当您尝试不支持的 URL 方案时,Safari 会警告用户它不知道如何处理它并停留在同一页面上。

因此,如果您给应用调用一些时间来激活,例如 300 毫秒,然后执行其他操作来响应该方案的不存在。

这不是最漂亮的,但它确实有效:

function startIThrown(){
  document.location = 'ithrown://restart';
  setTimeout(function(){
    if(confirm('You do not seem to have iThrown installed, do you want to go download it now?')){
      document.location = 'http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=293049283&mt=8&uo=6';
    }
  }, 300);
}

<a href="#" onclick="startIThrown()">Restart iThrown</a>

【讨论】:

  • 值得一试,但这确实是一个令人讨厌的解决方案。即使返回页面时 URL 方案通过,该函数也会被调用。因此,无论如何,用户都会收到警报弹出窗口。 1 或 2,取决于他的设备是否支持该方案。
  • @samvermette 有一个半复杂的解决方法。如果 url 方案有效,则让您的应用程序向您的服务器发送确认。然后当你回到应用程序时,让它 ping 服务器以查看应用程序是否已成功打开。复杂,但可行。
  • 如果未安装应用程序,有什么方法可以不显示这个可怕的不友好错误?
  • iOS 13.3 解决方案与“非常不友好的错误”配合得很好:gist.github.com/diachedelic/0d60233dab3dcae3215da8a4dfdcd434
【解决方案2】:

这是一个解决方案,当您从应用程序返回时不显示弹出窗口,它假设您离开的时间超过 400 毫秒:

function startiThrown() {
    document.location = appurl;
    var time = (new Date()).getTime();
    setTimeout(function(){
        var now = (new Date()).getTime();

        if((now - time)<400) {
            if(confirm('You do not seem to have iThrown installed, do you want to go download it now?')){
            document.location = 'http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=293049283&mt=8&uo=6';
            }
         }
    }, 300);
}

【讨论】:

  • 我们遇到了一个问题,这个解决方案中的“now”变量完全错误。我们可以在应用程序中等待几分钟,然后返回浏览器并获得确认。休眠唤醒过程似乎有问题。
【解决方案3】:

我发现pagehide 事件比依赖系统时间更强大。对于我们这些喜欢非 jQuery 的人来说,这里是 sn-p。

  var appurl = 'custom://url';
  var appstore = 'https://itunes.apple.com/us/app/your-app';

  var timeout;
  function preventPopup() {
    clearTimeout(timeout);
    timeout = null;
    window.removeEventListener('pagehide', preventPopup);
  }
  function startApp() {
    window.location = appurl;
    timeout = setTimeout(function(){
      if(confirm('You do not seem to have the App installed, do you want to go download it now?')){
        document.location = appstore;
      }
    }, 1000);
    window.addEventListener('pagehide', preventPopup);
  }

【讨论】:

  • 该代码不起作用。当模式存在并且它与可执行文件相关联时,浏览器会询问是否要运行该应用程序。该延迟导致超时到达,显然,confirm 函数将被执行。
【解决方案4】:

从 iOS 6.0 开始,Apple 推出了智能应用横幅,它可以满足我们大多数人的需求:

  • 如果应用未安装,请发送至 App Store。
  • 使用 app-argument 参数打开带有特定深层链接的应用。

包括以下元标记:

<meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL">

取自这里: Safari Web Content Guide

【讨论】:

    【解决方案5】:

    另一个很好的(至少在最新的浏览器版本中工作)解决方法是检查浏览器窗口在短暂超时后是否有焦点,这样只有当 URI 方案不起作用时,您才能向用户显示一个对话框

    HTML:

    <a class="uri-link" data-uri="qobuzapp://" href="#">URI</a>​
    

    Javascript(这里使用 jQuery):

    var windowHasFocus;
    
    $(window).focus(function() {
      windowHasFocus = true;
    }).blur(function() {
      windowHasFocus = false;
    });
    
    function goToUri(uri) {
      window.location = uri;
      setTimeout(function(){
        if (windowHasFocus) {
          if (confirm('You do not seem to have Qobuz installed, do you want to go download it now?')){
            window.location = 'http://www.qobuz.com';
          }
        }
      }, 100);
    }
    
    $('a').on('click', function(){ 
      goToUri($(this).data('uri')); 
    });​
    

    【讨论】:

    • 该代码不起作用。当模式存在并且它与可执行文件相关联时,浏览器会询问是否要运行该应用程序。该延迟导致超时到达,显然,confirm 函数将被执行。
    【解决方案6】:

    不,不是来自网页。

    【讨论】:

    • 我想我想起了一种应用程序可以检查这一点的方法,但我可能错了。
    • 感谢您的快速回答。就本机代码而言,可以通过 openUrl: 进行检查,所以我已经阅读...未测试
    • @Brent Royal-Gordon:不。原生 iPhone 应用程序可以通过调用 canOpenURL:. 进行检查
    • 这是“事实上正确,但实际上没有那么有用”的答案之一。 This answer 解决了 OP 可能应该首先提出的问题!
    【解决方案7】:

    这是前 2 个解决方案的变体。它将创建一个可以在 Google Chrome 中打开的链接。如果失败,它会使用 http

    打开链接
    <script>
     function checkChrome(h){
      document.location=h;
      var time = (new Date()).getTime();
      setTimeout(function(){
       var now = (new Date()).getTime();
       if((now-time)<400) {
        if(confirm('Missing Chrome. Download it now?')){
         document.location = 'http://itunes.apple.com/us/app/chrome/id535886823?mt=8';
        } else {
         document.location=h.replace('googlechrome','http');
        }
       }
      }, 300);
     }
    </script>
    
    <a href="googlechrome://www.google.com" onclick="checkChrome(this.href);return false;">Open Google with Chrome</a>
    

    【讨论】:

      【解决方案8】:

      这是基于 mrahman 的回答。如前所述,JoshNaro new Date() 在超时内调用时会返回错误的日期。测试表明,在停用应用程序之前启动的线程中,日期没有更新。

      激活后调用的更丑陋的 setTimeout 将使用当前日期创建一个新线程。

      这是在 iOS 8 上测试的。

      function startiThrown() {
          document.location = appurl;
          var time = (new Date()).getTime();
          setTimeout(function(){
              setTimeout(function(){ // <-- start new thread after activation
                  var now = (new Date()).getTime();
                  if((now - time)<400) {
                      if(confirm('You do not seem to have iThrown installed, do you want to go download it now?')){
                          document.location = 'http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=293049283&mt=8&uo=6';
                      }
                  }
              }, 10); // <-- start new thread after activation
          }, 300);
      }
      

      【讨论】:

        【解决方案9】:

        我尝试只使用 'pagehide' 事件,但它不适用于 Firefox。我在这里创建了这个版本http://jsfiddle.net/thiagomata/6tvoc4f1/2/,它适用于 Firefox、Google Chrome 和 Safari。我还没有在 Internet Explorer 中测试过。

        让它在 Firefox 中运行的必要条件是使用 Iframe 设置 src。这使我可以在不离开页面的情况下调用应用程序。

        <a class="uri-link" href="#" 
          data-uri-app="myapp://" 
          data-url-app-not-found="http://www.google.com?q=not-found-link"
          >
          Example 1
        </a>​
        <a class="uri-link" href="#" 
          data-uri-app="myapp://" 
          data-url-app-not-found="http://www.google.com?q=not-found-link"
          data-url-app-found="http://www.google.com?q=found-link"
          >
          Example 2
        </a>​
        <a class="uri-link"  href="#"
          data-uri-app="notexists://" 
          data-url-app-not-found="http://www.google.com?q=not-exists"
        >
          Example 3
        </a>​
        <iframe id="callapp" style="display:none"></iframe>
        

        【讨论】:

        • 不错的概念。尽管发现应用程序从未发生过。即使安装了应用程序(我尝试过 instagram://app),它也会触发未找到的应用程序。
        • 您是否尝试将超时设置得更大?将第 95 行中的值从 1000 更改为 9000(只是为了好玩)并告诉我会发生什么。
        【解决方案10】:

        我有这个评论 https://stackoverflow.com/a/18715513/49114 带有一个 jQuery 插件,可以将替代应用链接添加到常规链接。

        【讨论】:

        • 该插件无法解决您没有安装应用时的警报问题
        猜你喜欢
        • 2011-06-16
        • 1970-01-01
        • 2020-03-30
        • 1970-01-01
        • 2014-12-25
        • 1970-01-01
        • 2014-04-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多