Recently I saw a lot of friends do some interception to open in seconds, here are a few solutions to cause problems and solve the direction
NSURLProtocol
This solution resolves interception requests
+ (BOOL)canInitWithRequest:(NSURLRequest*)requestCopy the code
Intercept resources in the above method
- (void)startLoadingCopy the code
Replace in this method.
Issues involved
Question 1
+ (BOOL)canInitWithRequest:(NSURLRequest*)request interception all requests are intercepted without distinction, so there are many unknown factors
+ (void)registerPrefix:(NSString *)prefixUrlKey prefixUrl:(NSString *)prefixUrl{ NSCParameterAssert(prefixUrlKey); NSCParameterAssert(prefixUrl); if (BUisEmptyString(prefixUrlKey) || BUisEmptyString(prefixUrl)) { return; } [self doInitialize]; @synchronized(prefixDict) { [prefixDict setObject:prefixUrl forKey:prefixUrlKey];
}}Copy the code
Problem 2. The request for WKWebview was intercepted, causing body loss
This problem is a headache for students, but if you are an app, there are many solutions
Method 1: Get the body using HTTPBodyStream and assign it to it
- (NSMutableURLRequest *)getMutablePostRequestIncludeBody { NSMutableURLRequest * req = [self mutableCopy]; if ([self.HTTPMethod isEqualToString:@"POST"]) { if(! self.HTTPBody) { NSInteger maxLength = 1024; uint8_t d[maxLength]; NSInputStream *stream = self.HTTPBodyStream; NSMutableData *data = [[NSMutableData alloc] init]; [stream open]; BOOL endOfStreamReached = NO; [stream hasBytesAvailable]) will always return YES when processing image fileswhileThere's an endless loop.while(! endOfStreamReached) { NSInteger bytesRead = [streamread:d maxLength:maxLength]; if(bytesRead == 0) {// At the end of the file read endofstreamreach = YES; }else if(bytesRead == -1) {// File read error endOfStreamReached = YES; }else if(stream.streamError == nil) { [data appendBytes:(void *)d length:bytesRead]; } } req.HTTPBody = [data copy]; [stream close]; }}returnreq; }Copy the code
Method 2: Inject the intercepting JS code into the WK container so that the corresponding request is intercepted by the client
hookAjax
hookFetchCopy the code
Method 3: The request scheme of the front-end is customized and forwarded by the client
[NSURLProtocol registerClass:[XXURLProtocol class]];
[NSURLProtocol wk_registerScheme:@"xxscheme"];
WKURLSchemeTask
This solution only supports iOS11 and above, but can solve the problem of body loss
- (void)webView:(WKWebView *)webView startURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask
The above method starts intercepting and populating the data internally
However, students using this scheme found a problem, which can only intercept custom scheme, HTTP and HTTPS interception will crash, as shown in the following figure
Finally find an official API that doesn’t work…
Never mind, the solution is as follows:
Method 1. The front-end students modify scheme, all request schmes are changed to custom, so that you can customize interception.
Front OS: somebody else Android nothing you let me change… How to fit…
Em, that won’t tear, so…
Method 2. We hook the corresponding interception method and modify the interception rule.
In the code
+ (void)_hookHandlesURLScheme { xx_WebViewClassMethodSwizzle(self, @selector(handlesURLScheme:), @selector(xx_handlesURLScheme:)); }+ (BOOL)xx_handlesURLScheme:(NSString *)name {if ([name isEqualToString:@"http"] || [name isEqualToString:@"https"]) { return NO; } return[self xx_handlesURLScheme:name]; }Copy the code
Understand it… You hook it up and you can do whatever you want
Of course… When you have all the methods implemented and you find that your functionality can run and successfully intercept, you will find a problem.
Knowing what will happen next…
Please leave a message to contact me.
Tips are welcome.