【Swift】WKWebView加载HTTPS的链接

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Emperor_huanzi/article/details/83271770

WKWebVIew

OC:
HTTPS已经越来越被重视,前面我也写过一系列的HTTPS的相关文章HTTPS从原理到应用(四):iOS中HTTPS实际使用当加载一些HTTPS的页面的时候,如果此网站使用的根证书已经内置到了手机中这些HTTPS的链接可以正常的通过验证并正常加载。但是如果使用的证书(一般为自建证书)的根证书并没有内置到手机中,这时是链接是无法正常加载的,必须要做一个权限认证。开始在UIWebView的时候,是把请求存储下来然后使用NSURLConnection去重新发起请求,然后走NSURLConnection的权限认证通道,认证通过后,在使用UIWebView去加载这个请求。

在WKWebView中,WKNavigationDelegate中提供了一个权限认证的代理方法,这是权限认证更为便捷。代理方法如下:

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
         
        if ([challenge previousFailureCount] == 0) {
             
            NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
             
            completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
             
        } else {
             
            completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
             
        }
         
    } else {
         
        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);   
         
    }
}
// Swift:
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            if challenge.previousFailureCount == 0 {
                let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
                completionHandler(URLSession.AuthChallengeDisposition.useCredential,credential)
            }else{
                completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge,nil)
            }
        }else{
            completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge,nil)
        }
    }

这个方法比原来UIWebView的认证简单的多。但是使用中却发现了一个很蛋疼的问题,iOS8系统下,自建证书的HTTPS链接,不调用此代理方法。查来查去,原来是一个bug,在iOS9中已经修复,这明显就是不管iOS8的情况了,而且此方法也没有标记在iOS9中使用,这点让我感到有点失望。这样我就又想到了换回原来UIWebView的权限认证方式,但是试来试去,发现也不能使用了。所以关于自建证书的HTTPS链接在iOS8下面使用WKWebView加载,我没有找到很好的办法去解决此问题。这样我不得已有些链接换回了HTTP,或者在iOS8下面在换回UIWebView。如果你有解决办法,也欢迎私信我,感激不尽。

UIWebView

//
//  ViewController.m
//  02-HTTPS
#import "ViewController.h"

@interface ViewController ()<NSURLConnectionDelegate, UIWebViewDelegate>
{
    NSURLRequest *_request;
}
@property (weak, nonatomic) IBOutlet UIWebView *webView;

@end

@implementation ViewController

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

//  NSString *str = [@"http://www.baidu.com" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    NSString *str = [@"https://kyfw.12306.cn/otn/leftTicket/init" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL *url = [NSURL URLWithString:str];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    _request = request;

    if ([str hasPrefix:@"https://"]) { // https请求先发送connection请求,就会安装证书
        NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
        [connection start];
        NSLog(@"https请求");
    }else{  // http请求直接加载
        [self.webView loadRequest:request];
    }
}
#pragma mark - NSURLConnectionDelegate 加载https网页,需要实现代理下面两个方法

/**
 *  安装证书
 */
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    }
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

/**
 *  安装证书成功之后再加载https网页
 */
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse {

    self.webView.scalesPageToFit = YES;
    [self.webView loadRequest:_request];
}

/*
 // 另一种方法加载https网页
 - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
 return YES;
 }

  - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
 [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
 [self.webView loadRequest:_request];
 }
 */

#pragma mark - UIWebViewDelegate
/*
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{

    NSLog(@"%@", request.URL);
    return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{

}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{

}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error
{
}
*/
@end

猜你喜欢

转载自blog.csdn.net/Emperor_huanzi/article/details/83271770