2011-07-22 52 views
26

我们有一个使用UIWebView来显示内容的iOS应用程序。我们加载它与代码看起来像这样的数据:使用UIWebView忽略无效的服务器证书

NSURL *url = [NSURL URLWithString:myURLString]; 
NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
[_webView setDelegate:self]; 
[_webView loadRequest:request]; 

过去,这很好地工作的HTTP请求,但现在我们正在使用HTTPS对使用自签名的SSL证书的服务器。当以上运行时,webView:didFailLoadWithError:委托方法被调用,这个错误:

The certificate for this server is invalid. You might be connecting to a server that is pretending to be "blah.blah.blah.com" which could put your confidential information at risk."

我想简单地忽略无效的证书,并请求去,因为一个在移动Safari浏览器做。

我已经看到在使用NSURLConnection(例如参见HTTPS request on old iphone 3g)时如何解决此问题,但如何处理UIWebView

我想,以便它使用NSURLConnection做出请求,然后通过调用其loadHTMLString:baseURL:方法把结果放到Web视图我可以返工的代码,但是会变得复杂,当页面有图像,CSS, JavaScript等等。有更容易的方法吗?

回答

0

据我所知,这是不可能的,只有UIWebView。据我了解,您需要使用NSURLConnection来处理所有HTTP/HTTPS mojo,然后通过-loadHtmlString:baseURL:-loadData:MIMEType:textEncodingName:baseURL:将结果提供给UIWebView

21

请注意:该API当前不受支持,应该只能用于安全的测试环境。欲了解更多详情,请看CocoaNetics article

[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];将允许您忽略证书错误。您还需要将以下添加到您的文件的开头授予您访问这些私有的API:

@interface NSURLRequest (DummyInterface) 
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host; 
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host; 
@end 
+4

此方法的使用会让您的应用程序被AppStore拒绝。 – Franklin

+9

这是完美的使用自签名本地主机证书。我用'#if DEBUG'把它全部包围起来,以免被拒绝。 – bendytree

16

只是让每个人都知道...上面采用隐藏式接口的将不被接受苹果。他们寻找私有API的使用,这不是一个可接受的解决方案。所以,请不要发布上述解决方案作为解决问题的方式,因为尽管它有效,但它会在AppStore中向您购买拒绝。这使它无用。

以下是忽略无效服务器证书的ACCEPTABLE方法。您需要手动使用NSURLConnection的并加载数据的网页,像这样:

. 
. 
. 
    //Create a URL object. 
    url = [NSURL URLWithString:urlAddress]; 
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; 
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:requestObj delegate:self]; 
    [connection start]; 
} 

,然后在您的代理....

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace 
{ 
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{ 
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
    { 
     [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 
    } 
    else 
    { 
     [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; 
    } 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
[resultData appendData:data]; 
} 


- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    NSString *htmlString = [[NSString alloc] initWithBytes:[resultData bytes] length:[resultData length] encoding:NSUTF8StringEncoding]; 
    [webView loadHTMLString:htmlString baseURL:url]; 
} 
@end 

哪里resultData是你早期实例并在一个NSMutableData url和urlAddress都是你已经实例化并填充到其他地方的东西。

不幸的是,我目前还不知道如何在没有有效证书的情况下直接获取实际的UIWebView来加载页面。

你的,GC

+2

这种方法的问题在于你的webview不会显示任何动态内容 - CSS不会加载,JavaScript或任何嵌入式REST调用等。这是我目前的问题。有一个令人费解的方式来建议[这里](http://stackoverflow.com/questions/11573164/uiwebview-to-view-self-signed-websites-no-private-api-not-nsurlconnection-i) – Stretch

+0

这对于动态网页来说不是一个可接受的解决方案,例如。有重定向后取决于window.location的JavaScript。 UIWebView本身需要管理其位置并处理重定向,这是通过从NSURLConnection提供数据无法完成的。 – davidgoli

3

事实证明,一旦网站被取消的NSURLConnection的认证,则可以UIWebView中发出请求的网站。There is a complete explanation here.

+0

这个答案:http://stackoverflow.com/questions/11573164/uiwebview-to-view-self-signed-websites-no-private-api-not-nsurlconnection-i/15074358#15074358有一个聪明的方法解决这个问题。 – zadr