Interception request with WKWebView

Now I use UIWebView and canInitWithRequest: NSURLProtocol . I can intercept all requests and do what I want with them.

The new WKWebView does not have this method, and I did not find something like that.

Has anyone resolved this issue?

+10
source share
5 answers

You can intercept requests in WKWebView starting with iOS 8.0 by implementing the decidePolicyFor: navigationAction: method for 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 webView.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) } 
+2
source

in iOS 11, WKWebView came up with a custom schema handler called WKURLSchemeHandler , which you can use to intercept custom events. check out this project for more information. https://github.com/BKRApps/KRWebView

+1
source

There are many ways to implement an interceptor request.

  1. configure local proxy, use WKNavigationDelegate

     -[ViewController webView:decidePolicyForNavigationAction:decisionHandler:] 

    upload a new request and forward it to the local server, and on the local server side you can do something (for example, 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 the http / https system 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 three ways that you probably need to handle CORS and the message bodies that you want to delete, you overwrite the request for the browser option change ( Preflighted_requests ), you can use your own http header to replace the http body for the message bodies that will be deleted.

+1
source

I am blindly guessing since I only have a Windows computer. After reading the Apple Developer documentation, we have gathered information that may lead to some ideas on how to resolve the issue.

Based on WKWebView ,

Set the delegate property to an object that conforms to the WKUIDelegate protocol to track the loading of web content.

Also, I see that we can set navigationDelegate with

weak var navigationDelegate: WKNavigationDelegate? { get set }

The WKNavigationDelegate protocol methods help implement custom behaviors that run during the web view when accepting, loading, and completing a navigation request.

Then, after creating and installing our WKNavigationDelegate , we will override some methods to intercept something we can look for. I found the "Response to server actions" section, as they receive WKNavigation as a parameter. Moreover, you can skip WKNavigationAction and WKNavigationResponse to see if there is anything that can help us achieve our goal.

By the way, I just give some ideas about what to try so that we can solve this issue, ideas that may be 100% wrong, because I have not tried them myself.

0
source

You can use WKURLSchemeHandler to intercept every download request in WKWebView. The only drawback is that you cannot register an http or https scheme to intercept,

The solution to this problem: replace your http / https scheme with a URL with your own URL scheme, for example, xyz: //, for example, https://google.com can be downloaded as xyz: //google.com. You will now receive a callback in the WKURLSchemeHandler. there you again replace it back with https, load the data programmatically and call urlSchemeTask.didReceive (response)

This way, every https request will come to your handler.

0
source

Source: https://habr.com/ru/post/1011480/


All Articles