PhoneGap InAppBrowser:打开iOS Safari浏览器

时间:2013-05-13 09:55:08

标签: ios cordova inappbrowser

在我们的PhoneGap iOS应用程序中,我们使用InAppBrowser插件显示一些内容,我们需要在InAppBrowser中打开Safari中的页面。

我们怎样才能在Safari中打开InAppBrowser中

中的链接?

4 个答案:

答案 0 :(得分:6)

来自phonegap documentation

  

在新的InAppBrowser实例,当前浏览器实例或系统浏览器中打开URL。

var ref = window.open(url, target, options);
     
      
  • ref:引用InAppBrowser窗口。 (InAppBrowser)
  •   
  • url:要加载的URL(字符串)。如果URL包含Unicode字符,请在此处调用encodeURI()。
  •   
  • target:加载URL的目标,默认为_self的可选参数。 (字符串)

         
        
    • _self:如果URL在白名单中,则在Cordova WebView中打开,否则在InAppBrowser中打开。
    •   
    • _blank:在InAppBrowser中打开。
    •   
    • _system:在系统的网络浏览器中打开。
    •   
  •   

所以要回答你的问题,请使用:

window.open(your_url, '_system', opts);

请注意,域名需要列入白名单。


2014年4月25日更新:

我认为我有点误解了这个问题(感谢评论者@peteorpeter) - 你希望有一些方法可以点击InAppBrowser中的链接并在系统浏览器中打开它(例如iOS上的Mobile Safari)。这是可能的,但需要在应用程序开发人员和负责页面链接的人员之间进行一些深思熟虑和合作。

创建IAB实例时,会得到对它的引用:

var ref = window.open('http://foo.com', '_blank', {...});

您可以register a few event listeners对该引用:

ref.addEventListener('loadStart', function(event){ ... });

每次IAB的URL更改时(例如,单击链接,服务器返回302等等),都会触发此特定事件,您可以检查新URL。

要进入系统浏览器,您需要在URL中定义某种标志。你可以做任何事情,但是对于这个例子,让我们假设网址中有一个systemBrowser标志:

<强> ..... HTML富= 1和; systemBrowser =真

您将在事件处理程序中查找该标志,并在找到时将其踢出系统浏览器:

ref.addEventListener('loadStart', function(event){
    if (event.url.indexOf('systemBrowser') > 0){
        window.open(event.url, '_system', null);
    }
});

请注意,这是检测网址中的标记的最佳方法(可能会导致误报),我很确定PhoneGap白名单规则仍然适用。

答案 1 :(得分:3)

不幸的是target=_system在InAppBrowser中不起作用。 (但是,如果链接源自父应用程序,这将起作用。)

您可以向IAB添加一个事件监听器并嗅探特定的url模式,正如您在评论中提到的那样,如果适合您的用例。

iab.addEventListener('loadstart', function(event) {
   if (event.url.indexOf("openinSafari") != -1) { 
        window.open(event.url, '_system'); 
    } 
}

这里的'event'不是真正的浏览器事件 - 它是IAB插件的构造 - 并且不支持event.preventDefault(),所以IAB也会加载url(除了Safari)。您可以尝试在IAB 中处理该事件,例如:

iab.addEventListener('loadstop', function(event) {
   iab.executeScript('functionThatPreventsOpenInSafariLinksFromGoingAnywhere');  
}

......我没有测试过。

答案 2 :(得分:2)

此消息仅供说明:

如果你通过在loadstart上捕获一个链接打开另一个window.open,它将杀死分配给第一个IAB的事件处理程序。

例如,

iab = window.open('http://example.com', '_blank', 'location=no,hardwareback=yes,toolbar=no');
iab.addEventListener('loadstop', function(event) {console.log('stop: ' + event.url);});
iab.addEventListener('loaderror', function(event) { console.log('loaderror: ' + event.message); });
iab.addEventListener('loadstart', function(event) {
    if (event.url.indexOf("twitter") != -1){
        var ref2 = window.open(event.url, '_system', null);

    }
});

当第二个window.open执行时,它将终止你之前绑定的所有事件侦听器。此window.open执行后也不会触发loadstop事件。

我找到了另一种方法可以避免,但还没有找到......

答案 3 :(得分:0)

window.open()无法在InAppBrowser中为我工作,无论我是否添加脚本引用到cordova.js以获得对window.open(...'_system')的支持,所以我想出了以下内容解决方案隧道&#34;外部&#34;通过主题标签返回IAB主机的URL,以便在那里打开。

InAppBrowser实例内部(我使用AngularJS,但是如果您使用jQuery,则可以将angular.element替换为jQuery$

angular.element(document).find('a').on('click', function(e) {
    var targetUrl = angular.element(this).attr('href');
    if(targetUrl.indexOf('http') === 0) {
        e.preventDefault();
        window.open('#' + targetUrl);
    }
});

请注意,这是上面的原始window.open,而不是cordova.js的window.open。此外,处理程序代码假定所有以http开头的URL都应在外部加载。您可以根据需要更改过滤器,以允许在IAB中加载某些URL,而在Safari中加载其他URL。

然后,在创建InAppBrowser的父代码中:

inAppBrowser.addEventListener('loadstart', function(e) {
    if(e.url.indexOf('#') > 0) {
        var tunneledUrl = e.url.substring(e.url.indexOf('#') + 1);
        window.open(tunneledUrl, '_system', null);
    }
});

使用此解决方案,IAB仍保留在原始页面上,并且不会触发显示后退导航箭头,loadstart处理程序可以在Safari中打开请求的URL。