iOS webview无法加载网页Domain=NSURLErrorDomain Code=-1202

错误

在应用中由 http转为 https 时, 报错了, 下面是错误:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)或者
Error Domain=NSURLErrorDomain Code=-1202 “The certificate for this server is invalid. “

原因

这是由于你的 https的证书失效, 或者是自建证书, 你需要跳过验证, 允许其进行服务器的连接.

请求错误中的解决方案

1.一般的,如果用的 AFN 的话你可以加上以下代码:

AFSecurityPolicy * securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
//allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
//如果是需要验证自建证书,需要设置为YES
securityPolicy.allowInvalidCertificates = YES;
//validatesDomainName 是否需要验证域名,默认为YES;
//假如证书的域名与你请求的域名不一致,需把该项设置为NO
//主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
securityPolicy.validatesDomainName = NO;
//validatesCertificateChain 是否验证整个证书链,默认为YES
//设置为YES,会将服务器返回的Trust Object上的证书链与本地导入的证书进行对比,这就意味着,假如你的证书链是这样的:
//GeoTrust Global CA 
//    Google Internet Authority G2
//        *.google.com
//那么,除了导入*.google.com之外,还需要导入证书链上所有的CA证书(GeoTrust Global CA, Google Internet Authority G2);
//如是自建证书的时候,可以设置为YES,增强安全性;假如是信任的CA所签发的证书,则建议关闭该验证;
securityPolicy.validatesCertificateChain = NO;
requestOperationManager.securityPolicy = securityPolicy;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2.若还是不可进行请求, 你可以尝试在你的请求类中加入以下代码:

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler{
    NSLog(@"didReceiveChallenge");
//    if([challenge.protectionSpace.host isEqualToString:@"api.lz517.me"] /*check if this is host you trust: */ ){
    completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
//    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.加入代码后本人遇到的问题就解决了, 但是如果你的请求还有问题你可以参考以下,
这里写图片描述
和这个问题 http://stackoverflow.com/questions/33827351/how-to-solve-this-nsurlsession-nsurlconnection-http-load-failed-kcfstreamerrord

这里也重点推荐一篇文章是关于 ATS 的: App Transport Security(ATS)
https自建证书在 AFN中的设置
网络请求及各类错误代码含义总结

UIWebView中解决方案实例:

#import "LoginProTocalVC.h"

@interface LoginProTocalVC (){
    NSURLConnection *_urlConnection;
    NSURLRequest *_request;
    BOOL _authenticated;
    UIWebView *webV;
}

@end

@implementation LoginProTocalVC

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self configNavigationBar];
    [self configBody];
    // Do any additional setup after loading the view.
}
- (void)configBody{
    
   webV = [[UIWebView alloc]initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64)];
    [self.view addSubview:webV];
    
//    if (currentType == YBNetworkTest) {
//        [view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://services.xxx.com/newsdetail/4"]]];
//    }else if(currentType == YBNetworkT1Service){
//        [view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://t1services.xx.com/newsdetail/4"]]];
//    }else if (currentType == YBNetworkDistribution){
//        [view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://appservices.xxx.com/newsdetail/4"]]];
//    }else if (currentType == YBNetworkApp1Service){
//        [view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://app1services.xxx.com/newsdetail/4"]]];
//    }
    NSString *urlStr = @"";
    if (currentType == YBNetworkTest) {
        urlStr = @"https://www.xxx.com/newsdetail/4";
    }else if(currentType == YBNetworkT1Service){
        urlStr = @"https://www.xxx.com/newsdetail/4";
    }else if (currentType == YBNetworkDistribution){
        urlStr = @"https://www.xxx.com/newsdetail/4";
    }else if (currentType == YBNetworkApp1Service){
        urlStr = @"https://www.xxx.com/newsdetail/4";
    }
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
    
    webV.delegate = self;
    [webV loadRequest:request];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    
    NSLog(@"Did start loading: %@ auth:%d", [[request URL]absoluteString],_authenticated);
    if (!_authenticated) {
        _authenticated = NO;
        _request = request;
        _urlConnection = [[NSURLConnection alloc] initWithRequest:_request delegate:self];
        [_urlConnection start];
        return NO;
    }
    return YES;
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    NSLog(@"WebController Got auth challange via NSURLConnection");
    if ([challenge previousFailureCount] == 0) {
        _authenticated = YES;
        NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
    }else{
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"WebController received response via NSURLConnection");
    // remake a webview call now that authentication has passed ok.
    _authenticated = YES;
    [webV loadRequest:_request];
    
    // Cancel the URL connection otherwise we double up (webview + url connection, same url = no good!)
    [_urlConnection cancel];
}
-(void)configNavigationBar{
    //创建颜色背景View
    UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 64)];
    bgView.backgroundColor = [UIColor whiteColor];
    //     bgView.backgroundColor = [UIColor lightGrayColor];
    bgView.clipsToBounds = YES;
    [self.view addSubview:bgView];
    //创建返回按钮
    UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    backBtn.frame = CGRectMake(5 , 20, 40, 40);
    [backBtn setImage:[UIImage imageNamed:@"regist_vc1_nv_back"] forState:UIControlStateNormal];
    
    [backBtn addTarget:self action:@selector(backBtnClick) forControlEvents:UIControlEventTouchUpInside];
    [bgView addSubview:backBtn];
    
    UILabel *titltlabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, bgView.frame.size.width, 40)];
    titltlabel.textAlignment = NSTextAlignmentCenter;
    titltlabel.textColor = [UIColor blackColor];
    titltlabel.text = @"用户协议";
    //    titltlabel.font = [UIFont systemFontOfSize:15];
    titltlabel.font = kYBTitleFont;
    [bgView addSubview:titltlabel];
    
    
    UIImageView *lingImg = [[UIImageView alloc] initWithFrame:CGRectMake(0, bgView.frame.size.height-0.5, bgView.frame.size.width, 0.5)];
    lingImg.backgroundColor = [UIColor lightGrayColor];
    [bgView addSubview:lingImg];
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
 #pragma mark - Navigation
 
 // In a storyboard-based application, you will often want to do a little preparation before navigation
 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
 // Get the new view controller using [segue destinationViewController].
 // Pass the selected object to the new view controller.
 }
 */


- (void)backBtnClick {
    
    //zyp
    NSArray *viewcontrollers=self.navigationController.viewControllers;
    if (viewcontrollers.count>1) {
        if ([viewcontrollers objectAtIndex:viewcontrollers.count-1]==self) {
            //push方式
            [self.navigationController popViewControllerAnimated:YES];
        }
    }
    else{
        //present方式
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    
    //end
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end




你可能感兴趣的:(app苹果iOS类)