Cordova,为啥需要 InAppBrowser 插件才能在系统浏览器中打开链接

Posted

技术标签:

【中文标题】Cordova,为啥需要 InAppBrowser 插件才能在系统浏览器中打开链接【英文标题】:Cordova, why would InAppBrowser plugin be required to open links in system browserCordova,为什么需要 InAppBrowser 插件才能在系统浏览器中打开链接 【发布时间】:2015-08-25 15:54:51 【问题描述】:

我有一个 Cordova 应用程序,它是一个带有单个 html 文件的单页应用程序。

所有链接都应在系统浏览器中打开。我不想要一个“嵌入式”InAppBrowser,而是真正的本机系统/外部浏览器。

我们可以在任何地方找到使用 InAppBrowser 的代码示例,例如:

window.open('http://apache.org', '_system');

但是为什么我们需要安装 InAppBrowser,即使我们甚至不打算使用嵌入式浏览器?

关于链接的目标,有人真的可以解释 WebView 的行为吗?目前尚不清楚它应该用target=_blank 做什么,但除了打开一个新的浏览器窗口之外,我看不到它还能做什么。

请注意,问题似乎只出在 ios 上,因为使用 target=_blankandroid(带有 Crosswalk 插件)似乎总是可以正常工作并在新的本机浏览器窗口中打开。

【问题讨论】:

嗯,据我了解,您始终处于网络视图中。现在您要查询主系统浏览器。现在,正常的 _target 空白可能并不总是有效,尤其是在 cordova 支持的所有平台上。为了克服这个问题,我们使用通过原生层调用浏览器的 inappbrowser。通过这种方式,我们可以保证在所有受支持的平台上都能找到有效的解决方案。 @SaniYusuf 但是为什么不创建一个不是“InAppBrowserPlugin”并且在系统浏览器中打开所有带有_blank的链接的插件呢?我觉得该插件正在尝试解决 2 个不同的问题,其中一个没有在插件名称中明确说明(但不太确定,因为它没有真正解释) @jcesarmobile 我做到了,据我所知,实际上它使 Android 上的所有 Ajax 请求都失败了。这里也没有记录:github.com/apache/cordova-plugin-whitelist @jcesarmobile 您还可以在源代码插件中看到,此选项仅对 Android 本机代码有效,根据此警告日志,不推荐使用 allow-accessFound <access launch-external> within config.xml. Please use <allow-intent> instead.跨度> 对不起,评论前没试过,我现在试过了,你是对的。问题是,cordova 是一个用于创建移动应用程序的框架,因此,所有资源都应该是本地的,外部链接没有真正意义(至少对我而言)。如果您需要它们,那么您有 inAppBrowser 插件,它允许您在 inAppBrowser 或系统浏览器中打开链接。确实有点奇怪,您必须安装“inAppBrowser”插件才能启动外部浏览器,但是您可以创建自己的插件来启动没有 inAppBrowser 的浏览器 【参考方案1】:

所以我用我发现的东西来回答我自己的问题。 请注意,我只在 Cordova 5.1.1 上处理 iOS 和 Android(带有 Crosswalk 插件),它可能不适用于其他平台/版本。

需要 InAppBrowser

即使您不需要嵌入式浏览器,也需要 InAppBrowser 插件。这使得_system 目标可用,触发本机插件代码打开系统/外部浏览器。

所以该插件似乎是某种“二合一”插件:它允许使用嵌入式浏览器 + 它允许安全地强制外部系统浏览器打开。

目前尚不清楚默认 WebView 行为应该与 _blank 链接相关(也不清楚它是否以任何方式为 WebViews 标准化),但我发现没有这个插件就无法在 iOS 上打开外部浏览器或本机代码。

在 WebView 中打开 _self,在本机浏览器中打开 _blank

如果你像我一样不关心嵌入式浏览器,而只是想在现有应用程序中将所有 _blank 目标打开到本机外部浏览器,而不会有太多痛苦(特别是如果应用程序也是移动网站...),您可以在应用的开头运行以下代码:

    function openAllLinksWithBlankTargetInSystemBrowser() 
        if ( typeof cordova === "undefined" || !cordova.InAppBrowser ) 
            throw new Error("You are trying to run this code for a non-cordova project, " +
                    "or did not install the cordova InAppBrowser plugin");
        

        // Currently (for retrocompatibility reasons) the plugin automagically wrap window.open
        // We don't want the plugin to always be run: we want to call it explicitly when needed
        // See https://issues.apache.org/jira/browse/CB-9573
        delete window.open; // scary, but it just sets back to the default window.open behavior
        var windowOpen = window.open; // Yes it is not deleted !

        // Note it does not take a target!
        var systemOpen = function(url, options) 
            // Do not use window.open becaus the InAppBrowser open will not proxy window.open
            // in the future versions of the plugin (see doc) so it is safer to call InAppBrowser.open directly
            cordova.InAppBrowser.open(url,"_system",options);
        ;


        // Handle direct calls like window.open("url","_blank")
        window.open = function(url,target,options) 
            if ( target == "_blank" ) systemOpen(url,options);
            else windowOpen(url,target,options);
        ;

        // Handle html links like <a href="url" target="_blank">
        // See https://issues.apache.org/jira/browse/CB-6747
        $(document).on('click', 'a[target=_blank]', function(event) 
            event.preventDefault();
            systemOpen($(this).attr('href'));
        );
    

【讨论】:

iOS webview 上的默认行为是在同一个 webview 上打开链接,与你使用的目标无关 在带有 Cordova 5.3.3 的 iOS8 上,以“_blank”为目标的 window.open 在 InAppBrowser 而非本机浏览器中打开我的本地 pdf。 @RémyDAVID 你正确执行了我的openAllLinksWithBlankTargetInSystemBrowser 函数吗?因为它适用于我们的 iOS8 是的,但我的 PDF 是 本地(即“file://....pdf”) 对不起,我是 ionic 新手...在哪里放置这段代码?哪个文件?

以上是关于Cordova,为啥需要 InAppBrowser 插件才能在系统浏览器中打开链接的主要内容,如果未能解决你的问题,请参考以下文章

Cordova inAppBrowser 如何隐藏 URL 并仅显示完成按钮

cordova插件新的窗口实例打开连接: cordova-plugin-inappbrowser

Cordova/PhoneGap 打开下载的文件 (InAppBrowser)

[Cordova inAppBrowser 在App内打开浏览器]

在 inAppBrowser 中调用外部 URL

为啥在 ios/cordova 中抛出这个异常?