https环境下用UIWebView访问 http网页的解决办法

用NSURLProtocol。这是个抽象类。这个类不需要去init。所有的代码操作就是覆盖其方法。
这个类能拦截所有的网络请求。
具体用法就是子类化这个类。
使用前先去注册下自己

[NSURLProtocol registerClass:[CDURLProtocol class]];

其他就是继承NSURLProtocol,覆盖NSURLProtocol里的方法;

+ (BOOL)canInitWithRequest:(NSURLRequest *)request

是否去拦截的这个请求,交给你去处理。有点hook的
意思。

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request;

规范这个请求。貌似可以在这里更改请求信息。
和上面的方法有一样的说明,必须实现。

This is an abstract method; sublasses must provide an
    implementation.

上面的两个方法实现后会调用

- (void)startLoading

从这个开始你自己的网络请求。
用urlconnection去请求自己的请求。
最后的时候,当你离开这个网页是最好调一下这个

+ (void)unregisterClass:(Class)protocolClass;

这个子类的实现方法也没多少,我粘出来吧

#import "CDURLProtocol.h"

@interface  CDURLProtocol()

@property(nonatomic,strong)NSURLConnection *connection;

@end

@implementation CDURLProtocol 

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    //防止重复请求,UUID 为唯一标示
    if ([[NSURLProtocol propertyForKey:@"sssss" inRequest:request] length])
    {
        return NO;
    }else
    {
        [NSURLProtocol setProperty:[NSUUID new].UUIDString forKey:@"sssss" inRequest:request];
    }

    //其实放过https请求也可以哦。
//    return [scheme isEqualToString:@"https"];
    
    
    
    return YES;

}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
    return request;
}

- (void)startLoading
{
    NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];

    
    self.connection = [NSURLConnection connectionWithRequest:mutableReqeust
                                                    delegate:self];
    
    [self.connection start];
}
- (void)stopLoading
{
    [self.connection cancel];
    self.connection = nil;
}
- (id)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id )client
{

    
    self = [super initWithRequest:request cachedResponse:cachedResponse client:client];
    return self;
}

/*
 自制证书自己实现
 */
//- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
//{
//     SecTrustRef trust = challenge.protectionSpace.serverTrust;
//    NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
//    [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
//}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [self.client URLProtocol:self didFailWithError:error];
}

- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection
{
    NSLog(@"currentRequest is %@",connection.currentRequest.URL);
    
    if ([connection.currentRequest.URL.scheme isEqualToString:@"http"]) {
        
        return NO;
    }
    
    return YES;
}


- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    
    
    
    if ([connection.currentRequest.URL.scheme isEqualToString:@"http"]) {
        
         [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
    }else
    {
        //https 能缓存?,我也不太清楚。
         [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowedInMemoryOnly];
    }
    

   
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.client URLProtocol:self didLoadData:data];
}



//
//- (nullable NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
//{
//    
//    
//    [self.client URLProtocol:self didReceiveResponse:cachedResponse.response cacheStoragePolicy:cachedResponse.storagePolicy];
//    
//    return cachedResponse;
//}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self.client URLProtocolDidFinishLoading:self];
}


@end

感觉对这个玩意还不太熟,后期我会持续修改
最后老样子,附上demo

https://pan.baidu.com/s/1slfJolR

修改:2017年02月13日18:56:06
他们说WKWebView 不可用,我试了,可以用。说WK要做很多工作。经我测试:用我写的这个子类,其他工作都不用做。d
demo:
https://pan.baidu.com/s/1miJjdkW

你可能感兴趣的:(https环境下用UIWebView访问 http网页的解决办法)