2011-09-27 179 views
16

我有我的网页,如果它没有安装应用程序,它可以打开应用程序(如果它安装)或指向应用程序商店。 如果安装了应用程序(我称之为“MYAPP://”),这一切都有效。但是,如果未安装应用程序,Safari会显示错误消息“无法打开URL”,就是这样。有没有办法从JScript中禁用该消息,或者有另一种方法可以从JScript中找出安装应用程序(而不是点击应用程序URL)?iPhone浏览器:检查是否从浏览器安装iPhone应用程序

给主持人:我看到有人问similar question和主持人错误地标记为重复。请理解这个问题是关于从浏览器中完成的。

发现有些合适的解决方案here

顺便说一句,如果有人感兴趣的是如何做同样的事情为Android,这里是代码。我们正在使用Dojo库:

dojo.io.iframe.send({ 
    url: "yourApp://foo/bar", 
    load: function(resp) { 
     // nothing to do since it will automagically open App 
    }, 
    error: function() { 
     window.location = "go to Android market"; 
    } 
    }); 

回答

0

我认为你仍然可以使用应用程序的网址作为测试。尝试在try...catch块包装它,

try { 
    //run code that normally breaks the script or throws error 
} 
catch(e) { 
    //do nothing 
} 
4

这里是iOS上工作的代码,即使“无法打开URL”仍然显示。

window.location = "yourApp://foo/bar";  
    clickedAt = +new Date; 
    setTimeout(function() { 
     if (+new Date - clickedAt < 2000) { 
      window.location = "go to Android market"; 
     } 
    }, 500); 

感谢您的android解决方案。

+0

这里是iOS和Android应用重定向一个完整的JS例如:https://gist.github.com/FokkeZB/6635236#file-all-in-one-php – Justin

0

我已经合并了一些东西,并使用下面的代码来检查它是否是iOS设备,然后使用chazbot中的try/catch方法。不幸的是,该设备仍然向用户弹出一个弹出框,说该地址是无效的......任何人都知道这是否是尝试在“尝试”块中打开无效URL的预期行为?

var i = 0, 
    iOS = false, 
    iDevice = ['iPad', 'iPhone', 'iPod']; 

    for (; i < iDevice.length ; i++) { 
     if(navigator.platform === iDevice[i]){ iOS = true; break; } 
    } 

    try { 
     //run code that normally breaks the script or throws error 
     if (iOS) { window.location = "myApp://open";} 
    } 
    catch(e) { 
     //do nothing 
    } 
12

Branch我们用下面的代码的形式 - 注意的iframe适用于更多的浏览器。只需将您的应用的URI和App Store链接替换即可。顺便说一下,如果他们没有安装应用程序,使用iframe可以使错误消失。这很棒!

<!DOCTYPE html> 
<html> 
    <body> 
     <script type="text/javascript"> 
      window.onload = function() { 
       // Deep link to your app goes here 
       document.getElementById("l").src = "my_app://"; 

       setTimeout(function() { 
        // Link to the App Store should go here -- only fires if deep link fails     
        window.location = "https://itunes.apple.com/us/app/my.app/id123456789?ls=1&mt=8"; 
       }, 500); 
      }; 
     </script> 
     <iframe id="l" width="1" height="1" style="visibility:hidden"></iframe> 
    </body> 
</html> 

如果其他人有更好的解决方案来检测URI方案调用是否实际失败,请发帖!我没有看到过,而且我花了很多时间看。所有现有的解决方案都依赖于仍在页面上的用户和setTimeout触发。

+0

谢谢,这是最好的解决方案,我'已经看到。与其他人一样,如果未安装目标应用程序,则iOS 8会在打开网页之前提供“无效地址”消息。这只是选择任何一个选项,并做到这一点。现在,让它在Android上工作..! – JoLoCo

+0

祝你好运。每个浏览器都不一样。铬意向vs标准浏览器vs facebook webview vs twitter webview vs pinterest。这就是我每天在分店做的 –

+0

是的,这是一个真正的雷区,我发现了!如果我有任何重大突破,我会在这里发布它们... – JoLoCo

0

有几件事情可以改善其他答案。从iOS 9开始,链接可以在UIWebViewSFSafariViewController中打开。你可能想要以不同的方式处理它们。

SFSafariViewController跨应用程序和内置Safari共享Cookie。因此,在您的应用中,您可以通过SFSafariViewController发出请求,该请求会设置一个表示“我的应用已安装”的cookie。例如,你打开你的网站,要求你的服务器设置这样的cookie。然后,当您收到SFSafariViewController的请求时,您可以检查该cookie,如果找到该cookie,并将其重定向至MYAPP://,或者如果不存在,则重定向至应用商店。无需打开网页并执行javascript重定向,您可以从服务器上执行301。像MessagesSafari这样的应用共享这些cookie。

UIWebView是非常棘手的,因为它是完全的沙盒,并与其他任何cookie没有共享。所以你有什么已经在其他的答案被描述退却到:

window.onload = function() { 
    var iframe = document.createElement("iframe"); 
    var uri = 'MYAPP://'; 
    var interval = setInterval(function() { 
     // Link to the App Store should go here -- only fires if deep link fails     
     window.location = "https://itunes.apple.com/us/app/my.app/id123456789?ls=1&mt=8"; 
    }, 500); 
    iframe.onload = function() { 
     clearInterval(interval); 
     iframe.parentNode.removeChild(iframe); 
     window.location.href = uri; 
    }; 
    iframe.src = uri; 
    iframe.setAttribute("style", "display:none;"); 
    document.body.appendChild(iframe); 
}; 

我发现它烦人,这将提示用户,如果他们想离开当前的应用程序(去你的应用程序)即使你的应用程序没有安装。 (从经验上看,只有从UIWebView才是真实的,如果你从普通的Safari那里做到这一点,那不会发生),但这就是我们得到的!

您可以从您的服务器区别于SFSafariViewControllerUIWebView,因为他们有不同的用户代理头:在SFSafariViewController包含Safari浏览器UIWebView没有。例如:

Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E269 
-> UIWebView 

Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E269 Safari/602.1 
-> SFSafariViewController 

其他注意事项:

    在第一种方法
  • ,你可能要处理卸载的:如果用户卸载你的应用程序,你仍然有一个cookie,指出应用程序是有但事实并非如此,所以您最终可能会收到"Can not open URL"消息。我已经通过最终没有打开的应用程序(这我知道,因为在每一个应用程序打开的,我这个复位失败尝试的cookie)
  • 在第二种情况下,试了几次之后,除去该cookie处理它,但目前还不清楚如果你最好使用setIntervalsetTimeout。超时的问题在于,如果在提示符打开时触发,它将被忽略。例如,如果您打开Messenger的链接,当iframe尝试加载您的应用程序时,操作系统会询问您“离开Messenger?您即将打开另一个应用程序”。如果在超时500毫秒内没有任何响应,超时中的重定向将被忽略。
  • 最后即使UIWebView是沙箱,你可以给它一个cookie来识别它,通过它在你的深层链接,而这个ID保存为您的应用程序打开时,在你的服务器对应的设备与应用。下一次,如果您在来自UIWebView的请求中看到这样的cookie,则可以检查它是否与已知设备匹配,并像以前一样直接与301重定向。