UIWebView在访问正常签名的https网站是没有问题的,只是在访问自签名https时发生错误,无法正常展示页面内容。主要原因是证书认证失败。这里我们可以通过网络请求转发的方式来绕过证书认证失败的问题。
以下是具体的代码:
增加几个属性保存
@property (nonatomic, strong) NSURLRequest *originRequest;//原始网络请求
@property (nonatomic, strong) NSURLConnection *urlConnection;//转换为urlConnection
@property (nonatomic, assign) BOOL authenticated;//是否通过认证
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString*absoluteUrl = [[request URL] absoluteString];
NSLog(@"网页地址为:%@",[request URL]);
NSString*scheme = [[requestURL]scheme];
if([scheme isEqualToString:@"https"]) {
//如果是https:的话,那么就用NSURLConnection来重发请求。从而在请求的过程当中吧要请求的URL做信任处理。
if (!_authenticated) {
_authenticated=NO;
self.originRequest = request;
_urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[_urlConnection start];
returnNO;
}
}
return YES;
}
然后在NURLConnection delegate中设置
- (void)connection:(NSURLConnection*)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge
{
if([challenge previousFailureCount] ==0) {
_authenticated = YES;
//NSURLCredential 这个类是表示身份验证凭据不可变对象。凭证的实际类型声明的类的构造函数来确定。
NSURLCredential *cre = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
[challenge.sender useCredential:cre 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;
[self.webView loadRequest:self.originRequest];
// Cancel the URL connection otherwise we double up (webview + url connection, same url = no good!)
[_urlConnection cancel];
}
在实际应用中,大家可以自定义一个UIWebView,方便后续增加新的功能,比如js交互等等