我有一个网页,我有按钮,可以打开应用程序(如果已安装),或者如果未安装应用程序,则指向App Store。 如果安装了App,它都可以工作(我打电话给“MYAPP://”)。但是,如果未安装应用程序,Safari会显示错误消息“无法打开URL”,就是这样。有没有办法从JScript中禁用该消息,或者是否有其他方法可以从JScript中找到安装了应用程序(而不是点击应用程序URL)?
致主持人:我看到有人问similar question,主持人错误地将其标记为重复。请理解该问题具体是关于从浏览器中执行此操作。
找到了一些合适的解决方案here
BTW如果有人对如何为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 :(得分:13)
在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触发。
答案 1 :(得分: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解决方案。
答案 2 :(得分:0)
我认为你仍然可以使用app url作为测试。尝试将其包装在try...catch
块中,
try {
//run code that normally breaks the script or throws error
}
catch(e) {
//do nothing
}
答案 3 :(得分:0)
在使用chazbot的try / catch方法之前,我结合了一些内容并使用以下代码检查它是否是iOS设备。不幸的是,该设备仍向用户抛出一个弹出框,说明该地址无效......任何人都知道这是否是试图在“try”块中打开无效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
}
答案 4 :(得分:0)
您可以采取一些措施来改进其他答案。自iOS 9起,可以在UIWebView
或SFSafariViewController
中打开链接。您可能希望以不同方式处理它们。
SFSafariViewController
在应用程序和内置Safari中共享Cookie。因此,在您的应用中,您可以通过SFSafariViewController
发出请求,该请求会设置一个Cookie,其中包含&#34;我的应用已安装&#34;。例如,您打开您的网站,要求您的服务器设置此类cookie。然后,只要您收到来自SFSafariViewController
的请求,就可以检查该Cookie并在找到时重定向到MYAPP://
,如果您没有,则转到应用商店。无需打开网页并进行javascript重定向,您可以从服务器执行301。 Messages
或Safari
等应用共享这些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那样做,例如那不会发生)但是我们得到了所有这些!
您可以将UIWebView
与SFSafariViewController
区分开来,因为它们具有不同的用户代理标头:SFSafariViewController
包含 Safari ,而{{1没有。例如:
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
或"Can not open URL"
。超时问题是,如果在启用提示时触发,则会被忽略。例如,如果你打开Messenger的链接,操作系统会问你&#34;离开Messenger?您即将开设另一个应用程序&#34;当iframe尝试加载您的应用时。如果你没有在超时的500毫秒内做出任何反应,那么超时中的重定向将被忽略。setInterval
是沙盒,您也可以给它一个cookie来识别它,在深层链接中传递它,并在您的应用打开时将此ID与您服务器中的应用相对应。下次,如果您在来自setTimeout
的请求中看到此类Cookie,则可以检查它是否与应用程序中的已知设备匹配,并像以前一样直接使用301重定向。