UIWebView拦截资源请求

通过自定义NSURLProtocol子类并注册,可以监听和拦截UIWebView中的资源请求。项目需求是当拦截到特定埋点请求时,阻止发送并由客户端处理。遇到的问题包括对所有webView请求的预期拦截,但实际需理解NSURLProtocol的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中web页埋点以加载资源文件的形式发起请求,当客户端拦截到该请求时,要求放弃发送该请求,改为客户端统计此次埋点事件。

解决方案
NSURLProtocol可以拦截监听每一个URL Loading System中发出request请求。(如果不是这些类发出的请求NSURLProtocol就没办法拦截和监听了)

NSURLProtocol是一个虚基类,所以不能直接使用它,要想使用它就必须自定义一个类成为他的子类,然后实现他里面的必须实现的一些方法

+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
    /*
    //防止死循环,必要时使用
    if ([NSURLProtocol propertyForKey:protocolKey inRequest:request]) {
        return NO;
    }
    */
    NSString * urlString = request.URL.absoluteString;
    //需要处理请求返回YES
    return [WebViewStatistics webViewSendStatisticsWithURL:uslString];
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
    // return request;
    //这里直接拦截不发送
    return nil;
}

// 如需要重新发送请求可以在下列方法处理,不实现下面的方法,请求会以超时的形式结束。
// 踩的坑:一开始正常返回request,不实现下面的方法,结果请求加载超时影响webView加载完成回调代理方法。最后改为返回请求时直接返回nil,不再发起请求。
- (void)startLoading {
}

- (void)stopLoading {
}

除了这些你还需要在程序启动的时候注册该子类:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [NSURLProtocol registerClass:[IFStatisticsURLProtocol class]];

    return YES;
}

在发起请求时为NSURLSessionConfiguration的protocolClasses属性赋值(可以考虑使用Method Swizzling方法):

NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.protocolClasses = @[[IFStatisticsURLProtocol class]];

踩坑记录:一开始天真的以为webView加载的所有请求都会调用代理方法,o( ̄︶ ̄)o

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
     return YES;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值