error
When the application is changed from http to https, an error is reported. The following is an error:
NSURLSession/NSURLConnection HTTP load failed (kCFStream Error Domain SSL, -9813) or
Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. "
Reason
This is because your https certificate is invalid, or if you build your own certificate, you need to skip validation and allow it to connect to the server.
Solutions in Request Errors
1. Generally, if you use AFN, you can add the following code:
AFSecurityPolicy * securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
//Whether allowInvalid Certificates allow invalid certificates (i.e. self-built certificates), default to NO
//If you need to validate your build-in certificate, you need to set it to YES
securityPolicy.allowInvalidCertificates = YES;
//Whether validates DomainName needs to validate the domain name is YES by default;
//If the domain name of the certificate does not match the domain name you requested, you need to set this to NO.
//Mainly used in this case: the client requests a subdomain name, while the certificate has another domain name. Because the domain name on the SSL certificate is independent, if the domain name registered on the certificate is www.google.com, then mail.google.com can not be verified; of course, the domain name of the wildcard can be registered with money*.google.com, but this is more expensive.
securityPolicy.validatesDomainName = NO;
//Validates Certificate Chain verifies that the entire certificate chain is validated by default YES
//Setting YES compares the certificate chain on Trust Object returned by the server with the certificate chain imported locally, which means that if your certificate chain is like this:
//GeoTrust Global CA
// Google Internet Authority G2
// *.google.com
//Then, in addition to importing *. google.com, you need to import all the CA certificates in the certificate chain (GeoTrust Global CA, Google Internet Authority G2);
//If the certificate is self-built, it can be set to YES to enhance security; if it is a certificate issued by a trusted CA, it is recommended to close the validation;
securityPolicy.validatesCertificateChain = NO;
requestOperationManager.securityPolicy = securityPolicy;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
2. If requests are still unavailable, you can try to add the following code to your request class:
- (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. After joining the code, the problems I encounter are solved, but if there are problems with your request, you can refer to the following.
And this question http://stackoverflow.com/questions/33827351/how-to-solve-this-nsurlsession-nsurlconnection-http-load-failed-kcfstreamerrord
Here we also recommend an article about ATS: App Transport Security(ATS)
The Setting of https Self-built Certificate in AFN
Summary of Network Request and Meaning of Various Error Codes
Solution instances in 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{ //Create a Color Background 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]; //Create a return button 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 = @"User agreement"; // 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 mode [self.navigationController popViewControllerAnimated:YES]; } } else{ //present mode [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