【问题标题】:How can I open an external link in Safari not the app's UIWebView?如何在 Safari 中打开外部链接而不是应用程序的 UIWebView?
【发布时间】:2012-04-02 12:38:54
【问题描述】:

我有一个 Phonegap (cordova) 应用程序,我想在 phonegap WebView 中加载一些外部网页,并且当用户激活它们时我想在 safari 中加载其他外部网页。

通常大多数人都会遇到想要在 WebView 中打开外部链接的问题。将 OpenAllWhitelistURLsInWebView 设置为 YES(在 Cordova.plist/Phongap.plist 中)可以解决这个问题。

但我不想打开WebView的所有链接,只是一些。

我希望我可以调用 window.open('http://someexternalsite') 在 Safari 中打开,然后调用 window.parent.location.href = 'http://mysite' 在 WebView 中打开它。

知道怎么做吗?

【问题讨论】:

标签: javascript ios cordova


【解决方案1】:

如果你想在 safari 中打开的链接都包含一个公共字符串,你可以使用下一段代码。

- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSURL *url = [request URL];

    // Intercept the external http requests and forward to Safari.app
    // Otherwise forward to the PhoneGap WebView
    if ([[url scheme] isEqualToString:@"SCHEME"]) {
        [[UIApplication sharedApplication] openURL:url];
        return NO;
    }
    else {
        return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
    }
}

AppDelegate.m 中的这段代码将打开所有在 Safari 中使用指定 SCHEME 的 URL。

恐怕我能想到的只有这些了。

希望对你有帮助

更新:

代码应该放在 MainViewControler 中,至少对于 cordova 2.2.0。

该方法最初被注释。我不得不用它来重定向谷歌地图链接:

NSRange isGoogleMaps = [[url absoluteString] rangeOfString:@"maps.google.com" options:NSCaseInsensitiveSearch];
NSRange isGoogleTerms = [[url absoluteString] rangeOfString:@"terms_maps.html" options:NSCaseInsensitiveSearch];

if(isGoogleMaps.location != NSNotFound || isGoogleTerms.location != NSNotFound ) {
        [[UIApplication sharedApplication] openURL:url];
       return NO;
}
else 
    return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];

【讨论】:

  • 我希望有更好的方法,但看起来电话差距不支持我正在寻找的开箱即用的东西。谢谢!
  • 我也想用这个。这是您必须放入该文件的全部内容(并且在任何其他文件中都没有)才能使其工作吗?我只想在 safari 中打开所有外部链接 target="_blank"
  • 碰巧有人知道用android实现这个的方法吗?
  • if ( [request.URL.absoluteString rangeOfString:@"somedomain.com"].location != NSNotFound) { [[UIApplication sharedApplication]openURL:request.URL];返回否;这工作得很好。我从其他帖子中了解到 Cordova 2.0+ 将支持在 safari 中打开 _blank 目标,但尚未对其进行测试。我开始使用我的 android 版本,所以我还需要让它工作。如果它有效,我会报告回来
  • @AdamD 根据 phonegap 家伙的说法,你的建议应该有效 build.phonegap.com/blog/access-tagsbuild.phonegap.com/docs/config-xml 我不确定为什么它对我不起作用,可能是因为我使用的是 javascript window.open通过链接做到这一点。在那篇文章中还说,如果您不将 URL 添加到白名单,它将自动在 Android 的外部浏览器中打开(适用于 4.1,但由于某种原因不适用于 2.2 等早期版本)。在 iOS 上,您仍然需要将其添加到白名单中才能对 url 进行任何操作,无论是在 webview 中还是在 webview 中。
【解决方案2】:

只需在您的 javascript 中捕获具有target="_blank" 的所有链接,然后使用“_system”参数将它们传递给 window.open。这适用于 iOS 和 Android。

$(document).on('click', 'a[target="_blank"]', function(ev) {
  var url;

  ev.preventDefault();
  url = $(this).attr('href');
  window.open(url, '_system');
});

【讨论】:

  • 在 8.3 的 FB 应用中测试,它似乎不再工作了。
  • 如果它可以工作,那就太棒了,但在 iOS 8.xx 和 Android 5.xx 上测试并没有工作。原生似乎是唯一的出路。
  • _system 似乎是 PhoneGap/Cordova 的一个功能:docs.phonegap.com/en/2.3.0/…
【解决方案3】:

根据@TDeBailleul 的回答,这对我有用。基本上,任何具有 PDF 后缀的链接,或者如果它是我想在 Safari 中打开的特定页面,或者如果它不是 www.example.com/*(外部链接)中的页面,它将在新窗口:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

    // Open PDF files, Specific Pages, and External Links (not beginning with http://www.example.com) in Safari.app
    if (
        (navigationType == UIWebViewNavigationTypeLinkClicked) && 
        ([[[request URL] absoluteString] hasSuffix:@"pdf"] || [[[request URL] absoluteString] hasPrefix:@"http://www.example.com/specific-page.php"] || ![[[request URL] absoluteString] hasPrefix:@"http://www.example.com"])
        ) { 

        [[UIApplication sharedApplication] openURL:request.URL];
        return NO;
    } 

    return YES;
}

希望这对其他人有所帮助!

【讨论】:

  • 是的,这也适用于我。让类似的东西适用于 Android(2.2 至今)有什么运气吗?
【解决方案4】:

您可以(从 phonegap 1.5.0 开始)使用:

<a href="some://external/url" target="_blank">Click Me</a>

这应该会导致 phonegap 启动本机浏览器。

我认为 user868766 所指的是,要使上述内容正常工作,您需要将外部 url 列入白名单。 我一直在开发的应用程序在原生浏览器中打开了新闻报道的来源,因此我们在白名单中使用了 * 以确保我们没有排除任何来源。

希望对您有所帮助。

【讨论】:

  • 我试过这个,它似乎没有做任何事情。相反,我尝试在 javascript 中执行此操作,但它似乎没有做任何事情 window.open("some://external/url", "_blank");我还将 webview 中的 open all whitelist url 设置为 true,因为我的主应用程序实际上是一个 webapp,phonegap 应用程序只是用作登录页面,在经过身份验证后,它会重定向到 webapp。如果客户端需要更新,它应该重定向到另一个位置(不是 webapp)。
  • @MatthewLevine 您仍然需要在您的Cordova.plist 中允许您的外部 URL 的域。如果您需要允许任何域然后有一个 ExternalHosts 条目只有 *
【解决方案5】:

正确的做法是使用inAppBrowser plugin

使用 cordova CLI 安装它:

cordova plugin add org.apache.cordova.inappbrowser

然后,要在 Safari 上打开链接,只需使用:

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

在 npm 上有一个 newer version of the plugin

从 cordova CLI 安装它:

cordova plugin add cordova-plugin-inappbrowser

要在 safari 上打开网站,您可以使用

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

或者,如果您想像旧版本一样继续使用 window.open,您可以在设备就绪事件中执行此操作:

document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
    window.open = cordova.InAppBrowser.open;
}

【讨论】:

    【解决方案6】:

    在科尔多瓦 2.4 + iOS 上测试

    使用“_system”,无需更新任何配置

    http://docs.phonegap.com/en/2.3.0/cordova_inappbrowser_inappbrowser.md.html#InAppBrowser

    target: 在 (String) 中加载 URL 的目标(可选,默认值: “_self”)

    _self - 如果 url 在白名单中,则在 Cordova WebView 中打开,否则在 InAppBrowser 中打开 _blank - 始终在 InAppBrowser 中打开 _system - 始终在系统网络浏览器中打开

    【讨论】:

    • 嗨,我正在使用_system 作为:window.open(gameOverLink, '_system'); 但它对我不起作用。请建议
    【解决方案7】:

    如果你想在 safari 中打开一个外部 url,我认为这很有用:
    如果您使用 phonegap,这是 %100 保证的解决方案 - 在 ios6 中测试。
    要在 safari 中打开外部 url,请执行以下操作:

    1-在外部主机中添加您的链接(白名单)。例如http://google.com
    2-在 Cordova.plist 或 Phonegap.plist 中,将“OpenAllWhitelistURLsInWebView”从“是”更改为“否”
    3-在您的应用程序中添加 (target="_blank") 到您的链接
    例子

        <a href="http://google.com" target="_blank">Google.com</a>
    


    谢谢。

    【讨论】:

    • 是的,这适用于 iOS,但在 android 上不太好。我希望有一个好的跨平台方式来做到这一点。希望新的 phonegap 能解决它
    • “100% 保证解决方案 - 在 iOS6 中测试”。我希望你能认识到你有缺陷的逻辑!
    【解决方案8】:

    这对我很有帮助

    -(void)viewDidLoad
    {
       [super viewDidLoad];
        ////////////////////////
        NSString *urlAddress = @"http://www.playbuzz.org/";
        //NSURL *myURL = [NSURL URLWithString:urlAddress];
        myWebview.delegate = (id)self;
       [myWebview loadRequest:[NSURLRequest requestWithURL:[NSURL     URLWithString:urlAddress]]];
    }
    
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    
    
        //  open External Links (not beginning with www.playbuzz.org/ in Safari.app
        if (
            (navigationType == UIWebViewNavigationTypeLinkClicked) &&
            ( ![[[request URL] absoluteString] hasPrefix:@"http://www.playbuzz.org/"])
            ) {
    
            [[UIApplication sharedApplication] openURL:request.URL];
            return NO;
        }
    
       //open Internal links in uiwebview
       return YES;
    }`
    

    【讨论】:

      【解决方案9】:
      1. 将 target="_blank" 添加到您的链接中。 即:

        <a href="http://www.brandonbrotsky.com/" target="_blank"></a>
        
      2. 确保访问在您的 config.xml 中具有 * /> 的来源(确保它位于应用程序目录的根目录中,位于 www 文件夹上方。 即:

        <access origin="*" />
        
      3. 将以下代码添加到 MainViewController.m

        - (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
        {
            NSURL *url = [request URL];
        
            // Intercept the external http requests and forward to Safari.app
            // Otherwise forward to the PhoneGap WebView
            if ([[url scheme] isEqualToString:@"http"] || [[url scheme] isEqualToString:@"https"]) {
                [[UIApplication sharedApplication] openURL:url];
                return NO;
            }
            else {
                return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
            }
        } 
        

      我制作了一个简短的视频来解释如何解决这个问题:

      http://www.youtube.com/watch?v=zqbjXSnAR-Q&feature=c4-overview&list=UUefS6KLvFQVjhmL6hiBq4Sg

      希望对你有帮助!

      【讨论】:

      • 请在此处给出描述的答案,然后点击链接。仅发布链接将被标记为垃圾邮件。
      【解决方案10】:

      在 xcode 旁边

      //将代码放在/Classes/MainViewController.m

          - (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)­navigationType
      { NSURL *url = [request URL]; 
      // Intercept the external http requests and forward to Safari.app 
      // Otherwise forward to the PhoneGap WebView 
      if ([[url scheme] isEqualToString:@"http"] || [[url scheme] isEqualToString:@"https"]) { [[UIApplication sharedApplication] openURL:url]; return NO; } else { return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ]; }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-02
        • 2010-11-21
        • 2021-07-08
        • 1970-01-01
        • 1970-01-01
        • 2011-04-05
        • 1970-01-01
        相关资源
        最近更新 更多