如果用户尝试在Mobile Safari中加载https网页,并且服务器的证书验证检查失败(已过期,撤销,自签名等),则显示用户将显示一条警告消息,并询问他们是否要继续或不.
类似地,NSURLConnection提供了实施者首先决定如何检查证书的能力,然后在失败的情况下决定如何执行,因此在这种情况下也可以向用户显示警告并为他们提供继续加载的机会页面还是不.
但是,当在UIWebView中加载https页面时,似乎无法通过证书检查行为只是无法加载页面 – didFailLoadWithError:使用kcfURLErrorServerCertificateUntrusted调用,但是没有任何内容显示给用户.
这是不一致的 – UIWebView行为应该以类似于Safari的方式在iPhone本身中保持一致吗?
它也是一个尴尬,NSURLConnection允许这个NSURLRequest的完全灵活性:setAllowsAnyHTTPSCertificate是私有的.
有没有办法实现与Safari一致的行为,这个默认行为可以像NSURLConnection一样的定制吗?
干杯
附:
请不要光顾侧面的讨论,为什么有人想这样做,非常感谢.
解决方法
我发现如何做到这一点:
1)当页面被加载时,它将失败,因此添加一些类似以下的内容来执行以下操作:FalseLoadWithError:
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error if ([error.domain isEqualToString: NSURLErrorDomain]) { if (error.code == kcfURLErrorServerCertificateHasBadDate || error.code == kcfURLErrorServerCertificateUntrusted || error.code == kcfURLErrorServerCertificateHasUnknownRoot || error.code == kcfURLErrorServerCertificateNotYetValid) { display dialog to user telling them what happened and if they want to proceed
2)如果用户要加载页面,则需要使用NSURLConnection进行连接:
NSURLRequest *requestObj = [NSURLRequest requestWithURL:self.currentURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:10.0]; self.loadingUnvalidatedHTTPSPage = YES; [self.webView loadRequest:requestObj];
3)然后将此更改为shouldStartLoadWithRequest
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if (self.loadingUnvalidatedHTTPSPage) { self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [self.connection start]; return NO; }
4)实现NSURLConnectionDelegate为:
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { SecTrustRef trust = challenge.protectionSpace.serverTrust; NSURLCredential *cred; cred = [NSURLCredential credentialForTrust:trust]; [challenge.sender useCredential:cred forAuthenticationChallenge:challenge]; } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response; { NSURLRequest *requestObj = [NSURLRequest requestWithURL:self.currentURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:10.0]; self.loadingUnvalidatedHTTPSPage = NO; [self.webView loadRequest: requestObj]; [self.connection cancel]; }
这一切似乎都很好.