简体   繁体   English

在PhoneGap / Cordova中使用InAppBrowser在默认浏览器中打开链接

[英]Opening links in default browser with InAppBrowser in PhoneGap/Cordova

I'm building an app which wraps a responsive online website into an easy to use system using PhoneGap (specifically, PhoneGap Build) and InAppBrowser. 我正在构建一个应用程序,该应用程序使用PhoneGap(特别是PhoneGap Build)和InAppBrowser将响应性在线网站包装到易于使用的系统中。

The app loads and operates fine, except for one feature - opening external links in the system's default browser. 该应用程序加载并运行正常,除了一项功能-在系统的默认浏览器中打开外部链接。

This is 95% working, however specific cases cause issues where the link is redirecting (eg http://www.facebook.com redirects to https://www.facebook.com redirects to https://m.facebook.com ). 这是95%的工作方式,但是特定情况会导致链接重定向的问题(例如, http : //www.facebook.com重定向到https://www.facebook.com重定向到https://m.facebook.com ) 。

With my code, it is detecting that the URL is outwith the configured domain and opens it in a new system window, but also then loads the other two redirections AND also loads it within the app. 使用我的代码,它可以检测到URL超出了配置的域,并在新的系统窗口中将其打开,然后还加载了其他两个重定向,并将其也加载到了应用程序中。

The desired operation would be that it opens the link in the system's default browser and stops all further processing, redirection included. 所需的操作将是它在系统的默认浏览器中打开链接,并停止所有进一步的处理,包括重定向。

Note that just simply changing the target from the link on the HTML page to _system does not work, as it is external to the app since it is from a live website. 请注意,仅将target从HTML页面上的链接更改为_system无效,因为它在应用程序外部,因为它来自实时网站。

Any tips and advice is greatly appreciated. 任何提示和建议,我们将不胜感激。

The most important excerpts of the code are below: 该代码的最重要摘录如下:

From within the PhoneGap app: 从PhoneGap应用程序中:

//Called on deviceready
function launchSite(){
    // Get Webpage in InAppBrowser (using the _blank target) and hide it until loaded
    iabRef = window.open(url+'?inApp=true'), '_blank', 'location=no,hidden=yes');

    //Attach listener for external link intercepting
    iabRef.addEventListener('loadstart', iabLoad);
    //Attach listener for loading complete
    iabRef.addEventListener('loadstop', iabLoaded);     
}

//Check if links are external, if they are, open them in the system's default browser
function iabLoad(event){
    if(debug) alert('Page load request for ' + event.url);
    //Check the link to see if it is external, which is flagged by #appExt from injection.js
    if(event.url.indexOf('appExt') > -1){
        //Open the window using the _system target to use the system's default browser
        if(debug) alert('Opening '+event.url + ' in system window')
        window.open(event.url,'_system');

        if(debug) alert('Stopping anything more');
        //Mobile redirects keep triggering load events from initial link, stop the process now.
        window.stop(); // <-Does not stop
    }
    else{
        if(debug) alert('Opening normally without interference');
    }
}

//If window was hidden whilst loading, show it now that it has loaded
function iabLoaded(event){
    if(debug) alert('Showing IAB window');
    iabRef.show();
}

From a javascript file included in the responsive website: 从响应式网站中包含的javascript文件中:

function isExternal(url) {
    var match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
    if (typeof match[1] === "string" && match[1].length > 0 && match[1].toLowerCase() !== location.protocol) return true;
    if (typeof match[2] === "string" && match[2].length > 0 && match[2].replace(new RegExp(":("+{"http:":80,"https:":443}[location.protocol]+")?$"), "") !== location.host) return true;
    return false;
}

function goToPage(url, external){
    if(external)
        //Go to new URL with appended hash flag
        window.location=encodeURI(url)+'#appExt';
    else{
        //Show loading screen
        $('#app-overlay').css('display','block');
        //Wait for 100ms then change page, so the loading screen gets time to show
        setTimeout(function(){window.location=encodeURI(url)},100);
    }
}

$('a').on('click',function(e){
    e.preventDefault();

    if(isExternal($(this).attr('href'))){
        //If the URL is an external one, the app.js file will open the url in a new window after setting the appExt hash flag
        if(debug) alert('Stopping navigation from injection.js as external link detected');
        goToPage($(this).attr('href'), true);
    }
    else{
        //Otherwise, continue normally
        if(debug) alert('Regular link clicked');
        goToPage($(this).attr('href'), false);
    }

    //Cancel the default link operation, as we've already handled it
    return false;
});

Update: Continued tweaking and recompiling hasn't got me any further - anyone able to cast an eye over this for me? 更新:不断的调整和重新编译没有让我更进一步-有人能够为我着眼吗?

I'm not sure it's the best answer, but I "solved" it by keeping track of the last URL that was visited (through the startLoad event) and when I see someone linking somewhere to a different site than the one that is already loaded (using the startLoad event), I do a window.open with _system on the external URL, and then change the page of the InAppBrowser back to the last URL it was on (which I'm keeping track of). 我不确定这是否是最好的答案,但是我通过跟踪访问的最后一个URL(通过startLoad事件)以及当我看到某人链接到某个位置而不是已加载的站点的链接来“解决”它(使用startLoad事件),我在外部URL上使用_system进行window.open,然后将InAppBrowser的页面更改回其所在的最后一个URL(我一直在跟踪)。

Not the most elegant, but I couldn't find any other way to do it, and it seems to work not bad. 不是最优雅的,但是我找不到其他方法可以做到,而且看起来还不错。 Using cordova 3.6.3 (hoping to upgrade next week) and inAppBrowser 0.6.0. 使用cordova 3.6.3(希望下周升级)和inAppBrowser 0.6.0。 I can probably post code snippets if someone thinks it might be useful. 如果有人认为这可能有用,我可能会发布代码片段。

Do you try to do a window.open to open your link in the browser? 您是否尝试执行window.open以在浏览器中打开链接? In our app we do it like this 在我们的应用程序中,我们这样做

<span class="item_link"><a href="#" onclick="window.open(\''+ YourUrl +'\', \'_system\');">' + MoreLink + '</a></span>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM