【问题标题】:UIWebView not displaying my webpageUIWebView 不显示我的网页
【发布时间】:2016-07-08 14:29:17
【问题描述】:

对于一些背景信息,我尝试显示的网页是当前托管在 AWS 的 EC2 上的 Web 应用程序。后端是带有 Flask 的 Python,前端只是简单的 HTML/CSS。该 URL 具有 HTTP,因为它尚未使用 HTTPS 进行保护。打开此网页的 url 时,浏览器要求的第一件事是登录凭据(浏览器要求,而不是网站)。此页面确实在我的 iPhone 上的移动 Safari 中加载,并且 Safari 确实成功地要求提供凭据。如果我正确输入它们,它将正确加载页面。

所以我尝试了应用传输安全设置下的允许任意加载以及使用以下键的自定义异常域:

App Transport Security Settings                         Dictionary
Exception Domains                                       Dictionary
    my website URL                                      Dictionary
        NSIncludesSubdomains                            Boolean (YES)
        NSExceptionAllowsInsecureHTTPLoads              Boolean (YES)
        NSThirdPartyExceptionAllowsInsecureHTTPLoads    Boolean (YES)
        NSExceptionMinimumTLSVersion                    String (TLSv1.0)
        NSExceptionRequiresForwardSecrecy               Boolean (YES)

但是,每当我在模拟器上启动应用程序时,我得到的只是一个白屏(如果需要,可以发布屏幕截图)。

这是我在 ViewController.swift 中的代码:

import UIKit

class ViewController: UIViewController {

     @IBOutlet var WebView: UIWebView!

     override func viewDidLoad() {
         super.viewDidLoad()
         let url = NSURL(string: "My URL inserted here")
         let request = NSURLRequest(URL: url!)
         WebView.loadRequest(request)
     }
     override func didReceiveMemoryWarning() {
         super.didReceiveMemoryWarning()
     }
 }

如果我使用 Allow Arbitrary Loads,当我查看输出框时,它确实说“App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.”当我正确配置异常域时(使用允许删除任意负载)它也不会给我消息。只有当我使用 Exception Domain 更改设置时(同样,删除了 Allow Arbitrary Loads),我才会得到这个输出。

我开始认为这个问题超出了安全范围,如果我能采取任何建议或步骤来尝试解决这个问题,我将不胜感激,谢谢!

【问题讨论】:

  • 您提到浏览器要求在页面上进行身份验证 - 您是否为此使用基本身份验证?如果是这样,默认情况下,Mobile Safari 上弹出的用户名和密码不会出现在 UIWebView 中。我想说最好的方法是在 URL 中包含用户名和密码,例如:username:password@example.com
  • @wyzkid207 我不能说我听说过基本身份验证(绝对初学者开发者,每天仍在学习很多东西哈哈)。我刚刚尝试了你提到的方法,但没有奏效。有没有办法让 webview 显示一些身份验证提示?或者作为一个不同的旁注,有没有办法指定加载哪个浏览器 UIWebView,比如我可以让它打开 Safari、Chrome 等吗?谢谢:)
  • 如果你想在移动 safari 中打开 URL,你可以参考这个 SO:stackoverflow.com/questions/2899699/…(这可能是一个愚蠢的问题 - 但你可以像“apple.com”一样加载代码吗?你现在有吗?)
  • @wyzkid207 太棒了,我去看看。是的,无论我在其 URL 中使用 HTTP 还是 HTTPS,常规网站都会加载(前提是允许任意加载已启用)

标签: ios swift amazon-web-services uiwebview


【解决方案1】:

白屏有点奇怪,假设 401 会导致标准错误页面,但可能服务器为此设置了一个白页。 我的猜测是直接在 URL 中设置用户名和密码是行不通的,无论如何你都不应该这样做,而是依赖 WKWebViewwebView:didReceiveAuthenticationChallenge: 委托方法。

这里有一些示例代码,希望可以工作/提供帮助:

#import "ViewController.h"
@import WebKit;

@interface ViewController () <WKNavigationDelegate>

@property (nonatomic, strong) WKWebView *webView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:[WKWebViewConfiguration new]];
    self.webView.navigationDelegate = self;
    [self.view addSubview:self.webView];
    [self.webView setTranslatesAutoresizingMaskIntoConstraints:NO];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[_webView]-0-|"
                                                                     options:NSLayoutFormatDirectionLeadingToTrailing
                                                                     metrics:nil
                                                                       views:NSDictionaryOfVariableBindings(_webView)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[_webView]-0-|"
                                                                      options:NSLayoutFormatDirectionLeadingToTrailing
                                                                      metrics:nil
                                                                        views:NSDictionaryOfVariableBindings(_webView)]];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    NSURL *target = [NSURL URLWithString:@"http://yourhost.com/possiblePage.html"];
    NSURLRequest *request = [NSURLRequest requestWithURL:target];
    [self.webView loadRequest:request];
}

- (void)webView:(WKWebView *)webView 
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
                completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {

    NSURLCredential *creds = [[NSURLCredential alloc] initWithUser:@"username" 
                                                          password:@"password" 
                                                       persistence:NSURLCredentialPersistenceForSession];
    completionHandler(NSURLSessionAuthChallengeUseCredential, creds);
}

@end

这基本上是一个简单的ViewController 的实现文件(就像来自XCode 的单视图模板)。它还向您展示了如何添加WKWebView。一定要检查所有的委托方法等,这样你就知道它可以为你做什么。

显然,密码和用户名必须以某种方式设置,我想您可以使用一个简单的警报弹出窗口让用户输入此信息(这在原则上类似于 Safari)。对于第一个测试,您可以对其进行硬编码。另请注意,我在那里设置了一个示例子页面,只需使用您通常在桌面浏览器上使用的完全相同的 URL。哦,由于服务器没有 SSL,您需要允许任意加载

编辑:

RPM 在下面给出了一个很好的相关评论(谢谢),这是我最初没有想到的。该方法可能(实际上很可能)被多次调用。这最终还取决于您加载的网站。 RPM 对网站为什么会显示为纯白色的解释很到位。

无论如何,上面的webView:didReceiveAuthenticationChallenge:completionHandler: 方法只是一个简单的例子,假设你知道密码和用户名。通常它会更复杂,您不应该在每次调用用户输入凭据时都打开一个输入对话框。事实上,提供的challenge 提供了一些方法来设置对该委托方法的特定调用与之前的调用相关。例如,它有一个可能已经设置的proposedCredential 属性。 (是否是加载多个我不知道的资源的情况,试试吧。)另外,检查它的previousFailureCount等。很多这可能取决于你加载的网站和什么它需要得到。

【讨论】:

  • 感谢@gero。这是一个很好的答案!我认为使用 WKWebView 而不是 UIWebView 很重要。原因是对于网页请求的每个资源,都会调用委托方法来获取凭据。如果您使用 UIWebView,则不会发生这种情况。使用 UIWebView,您可以仅为页面请求提供凭据,而不是为页面中的所有项目提供凭据 - 这就是我的页面显示但它是空白的原因!
  • 嘿,感谢@RPM 提供的信息。我稍微扩展了答案(即使它现在已经旧了)。很高兴能帮到你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多