Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept request with WKWebView

Tags:

Now i'm using UIWebView and with canInitWithRequest: of NSURLProtocol i can intercept all requests and do with it what I want.

In the new WKWebView this method there isn't, and i not found something similar.

Has someone resolved this problem?

like image 637
Pol Avatar asked Oct 19 '16 13:10

Pol


2 Answers

You can intercept requests on WKWebView since iOS 8.0 by implementing the decidePolicyFor: navigationAction: method for the WKNavigationDelegate

 func webView(_ webView: WKWebView, decidePolicyFor         navigationAction: WKNavigationAction,         decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) {      //link to intercept www.example.com      // navigation types: linkActivated, formSubmitted,      //                   backForward, reload, formResubmitted, other      if navigationAction.navigationType == .linkActivated {         if navigationAction.request.url!.absoluteString == "http://www.example.com" {             //do stuff              //this tells the webview to cancel the request             decisionHandler(.cancel)             return         }     }      //this tells the webview to allow the request     decisionHandler(.allow)  } 
like image 117
Matthew Cawley Avatar answered Sep 18 '22 18:09

Matthew Cawley


there are many ways to implement intercepter request.

  1. setup a local proxy, use WKNavigationDelegate

    -[ViewController webView:decidePolicyForNavigationAction:decisionHandler:] 

    load new request and forward to local server, and at the local server side you can do something(eg. cache).

  2. private api. use WKBrowsingContextController and custom URLProtocol

    Class cls = NSClassFromString(@"WKBrowsingContextController"); SEL sel = NSSelectorFromString(@"registerSchemeForCustomProtocol:"); if ([(id)cls respondsToSelector:sel]) {     // 把 http 和 https 请求交给 NSURLProtocol 处理     [(id)cls performSelector:sel withObject:@"http"];     [(id)cls performSelector:sel withObject:@"https"]; } 
  3. use KVO to get system http/https handler.(ios 11, *)

    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; URLSchemeHandler *schemeHandler = [[URLSchemeHandler alloc] init]; [configuration setURLSchemeHandler:schemeHandler forURLScheme:@"test"]; NSMutableDictionary *handlers = [configuration valueForKey:@"_urlSchemeHandlers"]; handlers[@"http"] = schemeHandler; handlers[@"https"] = schemeHandler; 

    all the three ways you probably need handle CORS & post bodies to be stripped,you overwrite change browser`s option request( Preflighted_requests),you can custom http header to replace http body for post bodies to be stripped.

like image 31
user9517377 Avatar answered Sep 17 '22 18:09

user9517377