ios - UIWebView 不显示我的网页

标签 ios swift amazon-web-services uiwebview

对于一些背景信息,我尝试显示的网页是当前托管在 AWS EC2 上的 Web 应用程序。后端是 Python w/Flask,前端只是简单的 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()
     }
 }

如果我使用“允许任意加载”,当我查看输出框时,它不会显示“App Transport Security 已阻止明文 HTTP (http ://)资源加载,因为它不安全。可以通过应用程序的 Info.plist 文件配置临时异常。”当我正确配置异常域(删除允许任意加载)时,它不会给我消息也可以。仅有时当我使用异常域更改设置(再次删除允许任意加载)时,我才会得到此输出。

我开始认为这个问题超出了安全范围,非常感谢我可以采取的任何建议或步骤来尝试解决这个问题,谢谢!

最佳答案

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

这里有一些示例代码,希望能够工作/有帮助:

#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的单一 View 模板)。它还向您展示了如何添加 WKWebView。一定要确保检查所有委托(delegate)方法等,这样您就知道它可以为您做什么。

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

编辑:

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

无论如何,上面的 webView:didReceiveAuthenticationChallenge:completionHandler: 方法只是一个简单的示例,假设您知道 PW 和用户名。一般来说,它会更复杂,您不应该在每次调用用户输入凭据时都打开一个输入对话框。事实上,所提供的挑战提供了将对此委托(delegate)方法的特定调用设置为与之前的调用相关的方法。例如,它有一个可能已经设置的 proposedCredential 属性。 (是否是加载多个资源的情况,我不知道,只是尝试一下。)此外,检查其 previousFailureCount 等。这在很大程度上可能取决于您加载的网站及其需要获取的内容。

关于ios - UIWebView 不显示我的网页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38269168/

相关文章:

ios - Metal Compute 管道不适用于 MacOS,但适用于 iOS

ios - 谷歌地图地点选择器 iOS Swift

ios - 从 xib 实例化自定义表格 View 单元格失败

swift - 计算属性内的 NSNumberFormatter

mysql - 与 Amazon RDS 相比,Amazon Aurora 速度较慢

ios 如何正确使用 NSPredicate 将 NSString 与核心数据匹配?

android - 从 native 代码访问 AsyncStorage

ios - 当用户单击“注销”时,我想将 View Controller 关闭到第一个屏幕

java - AWS Android 聊天应用程序

mysql - 更改 Amazon RDS MYSQL Linux 服务器的 innodb_log_file_size 变量值