本文介绍了UIWebView查看自签名网站(没有私人API,不是NSURLConnection) - 是否可能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有很多问题要问:我可以获得 UIWebView 来查看自签名的HTTPS网站吗?

There's a load of questions which ask this: Can I get UIWebView to view a self signed HTTPS website?

答案总是涉及:


  1. 使用私人api调用 NSURLRequest allowsAnyHTTPSCertificateForHost

  2. 使用 NSURLConnection 代替 canAuthenticateAgainstProtectionSpace etc

  1. Use the private api call for NSURLRequest: allowsAnyHTTPSCertificateForHost
  2. Use NSURLConnection instead and the delegate canAuthenticateAgainstProtectionSpace etc

对我来说,这些都不行。
(1) - 意味着我无法成功提交到应用程序商店。
(2) - 使用NSURLConnection意味着收到初始HTML页面后必须从服务器获取的CSS,图像和其他内容不会加载。

For me, these won't do.
(1) - means I can't submit to the app store successfully.
(2) - using NSURLConnection means the CSS, images and other things that have to be fetched from the server after receiving the initial HTML page do not load.

有没有人知道如何使用UIWebView查看自签名的https网页,这不涉及上述两种方法?

Does anyone know how to use UIWebView to view a self-signed https webpage please, which does not involve the two methods above?

或者 - 如果使用 NSURLConnection 实际上可以用来渲染一个完整的CSS,图像和每一个网页其他 - 那会很棒!

Or - If using NSURLConnection can in fact be used to render a webpage complete with CSS, images and everything else - that would be great!

干杯,

拉伸。

Cheers,
Stretch.

推荐答案

最后我明白了!

你可以这样做:

正常使用 UIWebView 启动您的请求。然后 - 在 webView:shouldStartLoadWithRequest - 我们回复 NO ,而是使用相同的请求启动NSURLConnection。

Initiate your request using UIWebView as normal. Then - in webView:shouldStartLoadWithRequest - we reply NO, and instead start an NSURLConnection with the same request.

使用 NSURLConnection ,您可以与自签名服务器通信,因为我们可以控制身份验证通过额外的委托方法,这些方法不适用于 UIWebView 。因此,使用 connection:didReceiveAuthenticationChallenge 我们可以对自签名服务器进行身份验证。

Using NSURLConnection, you can communicate with a self-signed server, as we have the ability to control the authentication through the extra delegate methods which are not available to a UIWebView. So using connection:didReceiveAuthenticationChallenge we can authenticate against the self signed server.

然后,在 connection:didReceiveData 中,我们取消 NSURLConnection 请求,并使用 UIWebView 再次启动相同的请求 - 这将立即生效,因为我们已经通过了服务器身份验证:)

Then, in connection:didReceiveData, we cancel the NSURLConnection request, and start the same request again using UIWebView - which will work now, because we've already got through the server authentication :)

以下是相关的代码段。

注意:您将看到的实例变量属于以下类型:

UIWebView * _web

NSURLConnection * _urlConnection

NSURLRequest * _request

Note: Instance variables you will see are of the following type:
UIWebView *_web
NSURLConnection *_urlConnection
NSURLRequest *_request

(我使用实例var代表 _request 在我的情况下,它是一个包含大量登录详细信息的POST,但如果需要,您可以更改为使用传入的请求作为方法的参数。)

(I use an instance var for _request as in my case it's a POST with lots of login details, but you could change to use the request passed in as arguments to the methods if you needed.)

#pragma mark - Webview delegate

// Note: This method is particularly important. As the server is using a self signed certificate,
// we cannot use just UIWebView - as it doesn't allow for using self-certs. Instead, we stop the
// request in this method below, create an NSURLConnection (which can allow self-certs via the delegate methods
// which UIWebView does not have), authenticate using NSURLConnection, then use another UIWebView to complete
// the loading and viewing of the page. See connection:didReceiveAuthenticationChallenge to see how this works.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
{
    NSLog(@"Did start loading: %@ auth:%d", [[request URL] absoluteString], _authenticated);

    if (!_authenticated) {
        _authenticated = NO;

        _urlConnection = [[NSURLConnection alloc] initWithRequest:_request delegate:self];

        [_urlConnection start];

        return NO;
    }

    return YES;
}


#pragma mark - NURLConnection delegate

- (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;
    [_web loadRequest:_request];

    // Cancel the URL connection otherwise we double up (webview + url connection, same url = no good!)
    [_urlConnection cancel];
}

// We use this method is to accept an untrusted site which unfortunately we need to do, as our PVM servers are self signed.
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

我希望这可以帮助其他人解决我遇到的同样问题!

I hope this helps others with the same issue I was having!

这篇关于UIWebView查看自签名网站(没有私人API,不是NSURLConnection) - 是否可能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 13:45