iOS攔截http請求 ( 為小白使用者定製的精簡版本)

語言: CN / TW / HK

這是我參與8月更文挑戰的第12天,活動詳情檢視: 8月更文挑戰” juejin.cn/post/698796… ”

引言

今天使用者Naruto反饋之前的demo:https://download.csdn.net/download/u011018979/16768533有點複雜,因為他的需求是隻要拖入我自定義的NSURLProtocol子類到動態庫,就可以自動攔截http請求。

針對他的要求,今天特意寫了一個簡單的demo。

其實就是由原來的手動註冊我們的協議類,使用了小技巧,採用分類的形式在load方法進行自動註冊而已

目前demo是隻要載入NSURL類就會自動注入我自定義NSURLProtocol子類進行http 攔截,當然你也可以更換到其他分類,不一定是NSURL(只要是你覺得會觸發的類都行)

在這裡插入圖片描述

本文demo下載地址https://download.csdn.net/download/u011018979/16840774

I、原理

1、基於NSURLProtocol攔截請求:

HTTP 請求開始時,URL 載入系統建立一個合適的 NSURLProtocol 物件處理對應的 URL 請求,因此我們只需寫一個繼承自 NSURLProtocol 的類,並通過 - registerClass: 方法註冊我們的協議類,然後 URL 載入系統就會在請求發出時使用我們建立的協議物件對該請求進行處理。

2、採用分類的形式在load方法進行自動註冊協議類

II、基於NSURLProtocol攔截http請求

  • 自定義NSURLProtocol子類
  • 對[KNURLProtocol shareInstance].requestBlock =進行賦值;因為攔截的請求會交給requestBlockForRequst處理;可在這個block列印請求資訊進行除錯驗證
  • 註冊協議類:

    方式一:在app啟動的時候呼叫KNURLProtocol的addRequestBlock方法進行 方式二:採用分類的形式在load方法進行自動註冊協議類(針對動態庫/靜態庫專案)

2.1、採用分類的形式在load方法進行自動註冊協議類

```objectivec

import "NSURL+registerURLProtocolClass.h"

@implementation NSURL (registerURLProtocolClass)

+(void)load{ [super load];

[self requestBlock];

}

pragma mark 攔截全域性請求

  • (void)requestBlock{ [KNURLProtocol handleRequest:^NSURLRequest (NSURLRequest request) {
    NSLog(@"攔截到請求-%@",request);
    
    dispatch_async(dispatch_get_main_queue(), ^{
    

// self.blockTv.text = [self.blockTv.text stringByAppendingString:[NSString stringWithFormat:@"攔截到請求--%@\n",request]]; });

    return request;
}];

}

```

2.2、 自定義NSURLProtocol子類

  • 核心方法

```objectivec /** 決定請求是否需要當前協議物件處理

問:是自動攔截? 答:是,你可以自己寫個開關 或者自己定義攔截規則 目前demo只是判斷是URL 就進行攔截 (isUrl)

協議類的註冊,可採用分類的形式在load方法進行自動註冊

/ +(BOOL)canInitWithRequest:(NSURLRequest )request{

if ([NSURLProtocol propertyForKey:protocolKey inRequest:request]) {
    return NO;
}
NSString * url = request.URL.absoluteString;
return [self isUrl:url];

}

/** 對當前的請求物件需要進行哪些處理

/ +(NSURLRequest )canonicalRequestForRequest:(NSURLRequest )request { return [[KNURLProtocol shareInstance] requestBlockForRequst:request]; } -(NSURLRequest )requestBlockForRequst:(NSURLRequest *)request{ if(self.requestBlock){ return self.requestBlock(request); }else{ return request; } }

```

  • KNURLProtocol.h

```objectivec // // KNURLProtocol.h // KNURLProtocolDemo // // Created by mac on 2021/4/19. //

import

import "HSSingleton.h"

typedef NSURLRequest (^requestBlock) (NSURLRequest request);

NS_ASSUME_NONNULL_BEGIN

@interface KNURLProtocol : NSURLProtocol

@property (nonatomic, copy) NSURLRequest (^requestBlock)(NSURLRequest request);

HSSingletonH(Instance);

/* 攔截全域性請求 @param block 請求回撥,block返回修改後的請求 / +(void)handleRequest:(requestBlock)block;

/* 禁止所有網路請求 / +(void)cancelAllRequest;

/* 恢復所有網路請求 / +(void)resumeAllRequest;

@end

NS_ASSUME_NONNULL_END

```

  • KNURLProtocol.m

    更多內容請看原文:https://blog.csdn.net/z929118967/article/details/116021139

    歡迎關注公眾號:iOS逆向

see also

在這裡插入圖片描述

從CSDN下載demo資源:https://download.csdn.net/download/u011018979/16768533 1、文章:https://kunnan.blog.csdn.net/article/details/115690756

2、應用場景:

2.1、 自定義請求頭的HTTPHeaderField

2.2、針對NSURLSessionConfiguration設定代理IP和埠,讓一些特殊的請求走自定義的隧道IP和埠

2.3、對網路請求的資料進行報文級別的加密:使用NSURLProtocol來自動監聽HTTP請求並加密解密。

通過[NSURLProtocol registerClass: [NetworkInject class]];注入了自定義的NSURLProtocol類

3、原理:利用NSURLProtocol 攔截 HTTP 請求 基於NSURLProtocol實現iOS應用底層所有網路請求攔截(含網頁ajax請求攔截【不支援WKWebView】); HTTP 請求開始時,URL 載入系統建立一個合適的 NSURLProtocol 物件處理對應的 URL 請求,因此我們只需寫一個繼承自 NSURLProtocol 的類,並通過 - registerClass: 方法註冊我們的協議類,然後 URL 載入系統就會在請求發出時使用我們建立的協議物件對該請求進行處理。

4、特色功能:

4.1http-dns防止DNS劫持。

會直接從本地或特定伺服器地址進行DNS解析,是一種避免DNS劫持的措施

https://kunnan.blog.csdn.net/article/details/115868333 在這裡插入圖片描述

4.2 禁止網路代理抓包(開啟後使用代理方式抓包的程式無法抓到此App中的請求,且計時處於代理網路下也不會影響App本身的請求) https://kunnan.blog.csdn.net/article/details/115866030