【问题标题】:PhoneGap InAppBrowser: open iOS Safari BrowserPhoneGap InAppBrowser:打开 iOS Safari 浏览器
【发布时间】:2013-05-13 09:55:08
【问题描述】:

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

我们如何在 Safari 中打开 InAppBrowser的链接?

【问题讨论】:

  • 如果你更具体,你更有可能得到答案。什么时候需要打开 Safari?它是来自用户操作,还是出于其他原因?请扩展您的问题。
  • 从 InAppBrowser 我想在 Safari 浏览器中打开外部链接。我可以使用以下代码打开 Safari 浏览器。但在 InAppBrowser 中,同样的链接也是打开的。函数 iabLoadStart(event) { console.log("iabLoadStart: " + event.type + ' - ' + event.url); if (event.url.indexOf("openinSafari") != -1) { window.open(event.url, '_system'); } }
  • 那么如果你能打开Safari,究竟是什么问题?
  • 但在 InAppBrowser 和 Safari 浏览器中都打开了相同的链接。但它应该在 Safari 浏览器中打开,而不是在 InAppBrowser 中。
  • 尝试在函数中首先调用event.preventDefault(),然后再进行任何检查或打开 Safari。这将阻止执行默认的偶数操作。

标签: ios cordova inappbrowser


【解决方案1】:

来自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 中定义某种标志。你可以做很多事情,但是对于这个例子,我们假设 url 中有一个 systemBrowser 标志:

.....html?foo=1&systemBrowser=true

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

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

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

【讨论】:

  • 当链接源自 InAppBrowser inside 时,这不起作用,我认为这是提出的问题(至少在 Cordova 3.4.1/iOS 中)。在我的测试中,无论target 值如何,IAB 中的链接始终保留在 IAB 中。
  • 感谢您的产品。我更新了我的答案以解释它是如何工作的。
  • 'loadstart' 必须全部小写,'loadStart' 不起作用。此外,这不会阻止链接在 InAppBrowser 中加载,它会在 Safari 和 Safari 中加载。
【解决方案2】:

很遗憾,target=_system 在 InAppBrowser 中不起作用。 (不过,如果链接源自父应用程序,这将起作用。)

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

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

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

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

...我没有测试过。

【讨论】:

  • 抱歉,在更新我的答案之前,我什至没想过要阅读您的答案。我看到我们的建议基本相同。 :)
  • 不用担心 - 两个地方总比没有好!
【解决方案3】:

此消息用于澄清:

如果您通过在 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 事件。

我正在寻找另一种避免的方法,但还没有找到..

【讨论】:

  • 非常喜欢。您找到重新绑定事件的解决方案了吗?
【解决方案4】:

window.open() 在 InAppBrowser 中对我不起作用,无论我是否添加对 cordova.js 的脚本引用以获得对 window.open(...'_system') 的支持,所以我想出了以下解决方案,它通过隧道“外部" 通过主题标签返回 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。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多