iOS端网络拦截技术

作者: 践行者 | 来源:发表于2017-09-08 17:24 被阅读81次

    iOS端网络拦截技术

    NSURLProtocol

    NSURLProtocol是URL Loading System的重要组成部分,能够拦截拦截所有基于URL Loading System的网络请求。

    URL-Loading-sys.png

    可以拦截的网络请求包括NSURLSession,NSURLConnection以及UIWebVIew。
    基于CFNetwork的网络请求,以及WKWebView的请求是无法拦截的。
    代码不够完善Demo地址--https://github.com/softwarefaith/JiOSDNS

    如何使用NSURLProtocol

    NSURLProtocol是一个抽象类。创建他的一个子类:

     @interface AppDNSInterceptor : NSURLProtocol
    

    分为五个步骤:
    注册 -> 拦截 -> 转发 -> 回调 -> 完结

    1.注册

    对于基于NSURLConnection或者使用[NSURLSession sharedSession]创建的网络请求,调用registerClass方法即可。

    [NSURLProtocol registerClass:[NSClassFromString(@"AppDNSInterceptor") class]];
    

    对于基于NSURLSession的网络请求,需要通过配置NSURLSessionConfiguration对象的protocolClasses属性。

    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    sessionConfiguration.protocolClasses = @[[NSClassFromString(@"AppDNSInterceptor") class]];
    
    2.拦截

    是否要处理对应的请求。由于网页存在动态链接的可能性,简单的返回YES可能会创建大量的NSURLProtocol对象,因此我们需要保证每个请求能且仅能被返回一次YES.

    +(BOOL)canInitWithRequest:(NSURLRequest *)request {}
    +(BOOL)canInitWithTask:(NSURLSessionTask *)task { return [self canInitWithRequest:task.currentRequest];}
    

    是否要对请求进行重定向,或者修改请求头、域名等关键信息。返回一个新的NSURLRequest对象来定制业务

    +(NSURLRequest *)canonicalRequestForRequest:    (NSURLRequest *)request {
    //这里截取重定向 做定制化服务:比如修改头部信息 ,dns映射ip等操作
    NSMutableURLRequest *mutableRequest = [request mutableCopy];
    return mutableRequest;
    

    }

    3.转发
    -(instancetype)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id<NSURLProtocolClient>)client {
    
    AppDNSInterceptor *interceptor = [super initWithRequest:request cachedResponse:nil client:client];
    return interceptor;}
    
    -(void)startLoading {
    NSMutableURLRequest * request = self.request.mutableCopy;
    //    //给我们处理过的请求设置一个标识符, 防止无限循环,
    [NSURLProtocol setProperty: @YES forKey: kAppDNSInterceptorKey inRequest: request];
    self.connection = [NSURLConnection connectionWithRequest: request delegate: self];}
    
    4.注回调

    当网络收到请求返回时,还需要在将返回值给原来网络请求

    -(void)URLProtocol:(NSURLProtocol *)protocol wasRedirectedToRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse;
    -(void)URLProtocol:(NSURLProtocol *)protocol cachedResponseIsValid:(NSCachedURLResponse *)cachedResponse;
    -(void)URLProtocol:(NSURLProtocol *)protocol didReceiveResponse:(NSURLResponse *)response cacheStoragePolicy:(NSURLCacheStoragePolicy)policy;
    -(void)URLProtocol:(NSURLProtocol *)protocol didLoadData:(NSData *)data;
    -(void)URLProtocolDidFinishLoading:(NSURLProtocol *)protocol;
    -(void)URLProtocol:(NSURLProtocol *)protocol didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
    -(void)URLProtocol:(NSURLProtocol *)protocol didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
    
    5.完结
    - (void)stopLoading {
    [self.managerSession cancel];
    self.managerSession = nil;}
    

    代码不够完善Demo地址--https://github.com/softwarefaith/JiOSDNS

    参考文章

    1. UIWebView 拦截js,css

    相关文章

      网友评论

        本文标题:iOS端网络拦截技术

        本文链接:https://www.haomeiwen.com/subject/fmhnjxtx.html