美文网首页
离线加载原理,以及拦截任意Scheme

离线加载原理,以及拦截任意Scheme

作者: xiaoliang1 | 来源:发表于2023-04-10 15:16 被阅读0次

    今天看到阿里的mpass上有离线加载H5,简单研究了这里用WebKit的WKURLSchemeHandler那套,非NSURLProtocol,间接的跨域。其实拿来做逆向破解也不是不可以
    主要code:

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.webHandler = [[MySchemeHandler alloc] init];
        WKWebViewConfiguration *webViewConfiguration = [[WKWebViewConfiguration alloc] init];
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"myScheme://myScheme.test.cn/index.html"] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10.0f];
        [webViewConfiguration setURLSchemeHandler:self.webHandler forURLScheme:@"myScheme"];
        [webViewConfiguration setURLSchemeHandler:self.webHandler forURLScheme:@"http"];
        self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:webViewConfiguration];
        [self.webView loadRequest:request];
        [self.view addSubview:self.webView];
    }
    

    这里支持http、https的拦截
    MySchemeHandler.m的主要代码:

    - (void)webView:(nonnull WKWebView *)webView startURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
    
        NSLog(@"拦截到请求的URL:%@", urlSchemeTask.request.URL);
        NSString *localFileName = [urlSchemeTask.request.URL lastPathComponent];
        
        
        if([localFileName isEqualToString:@"getIp.php"]){
            //拦截到的 http的XMLHttpRequest的异步请求
            NSURLSessionDataTask *session = [[NSURLSession sharedSession] dataTaskWithRequest:urlSchemeTask.request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                
                [urlSchemeTask didReceiveResponse:response];
                [urlSchemeTask didReceiveData:data];
                [urlSchemeTask didFinish];
            }];
            [session resume];
            return;
        }
        NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"];
        NSString *html = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];
        NSData *data = [html dataUsingEncoding:4];
        NSString *fileMIME = [self getMIMETypeWithCAPIAtFilePath:path];
        NSDictionary *responseHeader = @{
                                         @"Content-type":fileMIME,
                                         @"Content-length":[NSString stringWithFormat:@"%lu",(unsigned long)[data length]]
                                         };
        NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@", @"myScheme://myScheme.test.cn/", @"index.html"]] statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:responseHeader];
        [urlSchemeTask didReceiveResponse:response];
        [urlSchemeTask didReceiveData:data];
        [urlSchemeTask didFinish];
    }
    

    实现拦截http,https的拦截的主要代码:

    CHDeclareClass(WKWebView)
    CHClassMethod1(BOOL, WKWebView, handlesURLScheme, NSString *, urlScheme) {
        
        if([urlScheme isEqualToString:@"http"] || [urlScheme isEqualToString:@"https"]) {
            
            return NO;
        }
        
        return CHSuper1(WKWebView, handlesURLScheme, urlScheme);
    }
    __attribute__((constructor())) static void entry3() {
        
    //   写到 XLWebViewConfiguration load 也可
        CHLoadLateClass(WKWebView);
        CHClassHook1(WKWebView, handlesURLScheme);
    }
    

    代码demo:https://github.com/LoveSVN/MySchemeHandler.git
    最后的效果图:

    WechatIMG6.jpeg WechatIMG3.png WechatIMG4.png WechatIMG5.png

    相关文章

      网友评论

          本文标题:离线加载原理,以及拦截任意Scheme

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